Skip to main content

References: Second Names for Objects

intermediate20 min readLesson 67 of 204

Bind once, borrow forever โ€” when to pass by value, T&, and const& โ€” and the rules that keep references safe.

A reference is a second name for an existing object. Once bound, a reference can never refer to anything else โ€” assignment goes through it to the object. References must be initialized and can never be null.

void double_it(int& out) { out *= 2; }       // non-const: writes through

void report(const std::string& name) {       // const&: read-only borrow
    std::cout << name << '\n';
}

int main_cj_reference() {
    int x = 5;
    int& alias = x;         // binding, not copying
    alias = 9;              // x is now 9
    double_it(x);           // x is now 18
    return 0;
}

Choosing between by-value, by-reference, and const&

| You want... | Pass by | Why | |---|---|---| | a private copy the callee may change | value | cheap for small types | | to modify the caller's object | T& | the callee writes through | | read-only access, no copy | const T& | zero copy, cannot write | | an optional "no object" state | pointer (later) or std::optional | references cannot be null |

Rules that keep references safe

  • Never return a reference to a local โ€” the object dies before the caller reads it.
  • Range-based loops over containers should take const auto& (read) or auto& (modify).
  • A reference member makes a type non-assignable; usually prefer a pointer or value member.
std::vector<int> data{3, 1, 2};
for (const auto& value : data) std::cout << value;   // read: no copy
for (auto& value : data) value *= 10;                // write in place

Now practice

References: borrow and write throughWarm-up with references: mutate through an alias, count without copying, swap in place.3 challenges ยท ยท ~25 min