← Back to all posts

09 C++ Notes

References

C++ Notes


Introduction

Declaration

C++
int x{10};
int& y1{x};   // preferred (braces initialization)
int& y2(x);   // functional initialization
int& y3 = x;  // assignment initialization

Const References

C++
// non-const reference: can read and write through y
int x{10};
int& y{x};
y = 20; // allowed, x becomes 20

// const reference: can only read through y
int x{10};
const int& y{x};
// y = 20; -- not allowed, compiler error
x = 20; // still allowed directly through x

There is no such thing as const int& const y. Double const on a pointer makes sense because pointers can be rebound, so you sometimes want to lock the binding separately from the value. References are already permanently single-bound from declaration, so an extra const to prevent rebinding is meaningless, and it results in a compiler error rather than a redundant no-op.

References vs Pointers

ReferencesPointers
No dereferencing needed. Read and write directly through the alias name as if it were the original variable.
Cannot be rebound. Once declared to refer to a variable, it refers to that variable for its entire lifetime.
Must be initialized at declaration. There's no such thing as an empty or null reference in standard C++.
Must use the dereference operator * to read or write the value at the pointed-to address.
Can be repointed to a different variable or memory address at any time after declaration.
Can be declared uninitialized, which means it contains a garbage address that must never be used.

Code Example: main.cpp

C++
#include <iostream>

int main() {
    int x{10};
    int& y{x}; // y is an alias for x, same address, same value

    std::cout << "BEFORE CHANGES:\n";
    std::cout << "x:  " << x  << '\n';  // prints: 10
    std::cout << "y:  " << y  << '\n';  // prints: 10 (same object)
    std::cout << "&x: " << &x << '\n';  // prints: address of x
    std::cout << "&y: " << &y << "\n\n"; // prints: same address as &x

    y = 15; // modifying through the alias modifies the original

    std::cout << "AFTER CHANGES:\n";
    std::cout << "x:  " << x  << '\n';  // prints: 15 (changed via y)
    std::cout << "y:  " << y  << '\n';  // prints: 15
    std::cout << "&x: " << &x << '\n';  // prints: same address (unchanged)
    std::cout << "&y: " << &y << '\n';  // prints: same address (unchanged)

    return 0;
}

Closing

References are what pointers look like once you strip out the parts that make them dangerous: no rebinding, no dereferencing, no null state. That trade-off, less flexible in exchange for less to get wrong, is exactly why C++ leans on references so heavily once you get into functions and classes. Next up, char arrays and string manipulation.

← Previous 08 - Pointers, Part 2: Safety and Arithmetic Next → 10 - Char Arrays and String Manipulation