Create References
Lesson outline
Fundamentals of References
A reference in C++ is an alias - another name for an existing object (or function). Unlike pointers, you use a reference just like the object itself; there is no separate dereference operator to read or write the referred-to value.
Key characteristics:
- Must be initialized at the time of declaration (for data members: in the constructor's member-initializer list).
- Cannot be reseated to refer to a different object after initialization.
- Cannot be null in well-defined code (you can bind a reference-to-pointer to a null pointer value, but the reference itself still refers to that pointer object).
- Behaves as the underlying object in expressions (no explicit
*needed).
Reference Declaration Syntax
Use the ampersand (&) in a declaration to make a reference type. Here & is part of the type, not the address-of operator.
Reference Usage Examples
References are commonly used for aliasing, function parameters, and modifying data directly.
Binding Temporaries with const&
A const T& can bind to a temporary, extending the temporary's lifetime to the end of the full-expression. This is useful to avoid copying while accepting both lvalues and rvalues.
Rvalue References & Move/Forwarding (C++11+)
An rvalue reference (T&&) can bind to temporaries and enables move semantics. In templates, a parameter of the form T&& (with T deduced) is a forwarding reference that can bind to both lvalues and rvalues; use std::forward to preserve value category.
Reference Collapsing & Reference-Qualified Members
Reference collapsing rules (in templates and auto/decltype contexts):
T& &→T&T& &&→T&T&& &→T&T&& &&→T&&
Member functions may be qualified with &/&& to restrict calls to lvalue or rvalue objects.
Common Pitfalls
- Returning a reference to a local variable (dangling reference; undefined behavior).
- Binding references to temporaries whose lifetime isn't extended (dangling).
- Assuming references have independent storage or addresses (they alias another object).
- Attempting to create references to references directly (use
std::reference_wrapperif you need copyable/reference-like semantics).