█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/C++/References and const Correctness
40 minIntermediate

References and const Correctness

After this lesson, you will be able to: Use references vs pointers correctly, apply const correctness, and pass parameters efficiently.

References + const are how C++ stays fast without giving up safety. Get them right and your code is a joy to read.

Prerequisites:Classes and OOP in C++

References vs pointers

References are pointers that can't be null or rebound.

tsx
int x = 5;
int y = 10;
int* p = &x; // pointer: can be null, can be rebound
p = &y; // OK
p = nullptr; // OK
*p = 20; // would crash if null
int& r = x; // reference: must initialize, cannot rebind
// int& r2; // ERROR: must initialize
r = y; // this ASSIGNS y's value to x; doesn't rebind
r = 100; // sets x to 100 (r is still bound to x)
// Use reference when: you'll always have a valid object
// Use pointer when: optional/nullable, dynamic allocation, or pointer arithmetic

Const correctness

Apply const everywhere you can. It's documentation + compiler-enforced.

tsx
// Parameter passing rules:
void byValue(int x); // small types (int, double, ptr), pass by value
void byConstRef(const std::string& s); // expensive-to-copy + read-only, const ref
void byRef(std::string& s); // expensive-to-copy + mutate, ref
void byPointer(std::string* s); // optional/nullable, pointer
// Const member functions: doesn't modify *this
class User {
std::string name_;
public:
const std::string& name() const { return name_; } // const member fn
void setName(const std::string& n) { name_ = n; } // non-const member fn
};
const User alex("Alex");
alex.name(); // OK, const fn callable on const obj
// alex.setName("x"); // ERROR, non-const fn not callable on const obj

Parameter passing cheat sheet

int / float / pointer / small struct (<= 16 bytes): pass by value. std::string / std::vector / custom class (read-only): pass by `const T&`. Same but mutable: pass by `T&`. Optional/nullable: pass by `T*` or `std::optional<T>`. Sink parameter (you'll move-from it): pass by value + `std::move` inside.

💡 Why references win

Can't be null → fewer crash paths. Can't be rebound → no aliasing surprises mid-function. Same machine code as a pointer → zero cost. Reads more cleanly: `f(x)` vs `f(&x)`.

Common mistakes

Returning references to local variables (dangling reference UB). Skipping `const` everywhere (loses compiler help). Passing big types by value (silent perf hit). Using pointers where a reference would do (extra null-check noise).

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Classes and OOP in C++
Back to C++
The Standard Template Library (STL)→