C++ References, Pointers, and Const
Distinguish values, references, and pointers, express optional non-owning access, and apply const correctly without creating dangling lifetimes.
Before this lesson
Explain value reference and pointer semantics
Use const references for read-only borrowing
Detect null and dangling lifetime risks
The short answer
A reference is an alias that must bind to an object, while a pointer stores an address and may be null or reseated. Neither automatically owns the object; lifetime and mutation must be clear at every interface.
Values aliases and addresses differ
A value parameter receives an independent object. A reference parameter names the caller's object. A pointer parameter receives an address value and can be checked, copied, or changed to point elsewhere. These choices communicate different contracts.
Copying is often exactly right for small values and owned snapshots. Borrowing avoids a copy but ties use to another object's lifetime. Do not reach for pointers solely to appear efficient; first state ownership, optionality, and mutation.
| Form | Can be absent? | Typical meaning |
|---|---|---|
| Widget value | No | Independent object or copy |
| Widget& | No | Required mutable borrow |
| const Widget& | No | Required read-only borrow |
| Widget* | Yes | Optional mutable access |
| const Widget* | Yes | Optional read-only access |
References express required borrowing
A reference must bind to an object when initialized. Changes through a non-const reference affect that object. A const reference allows observation without mutation and can bind to temporary values for a limited lifetime.
References do not extend every lifetime and do not own storage. Returning a reference to a local object is invalid. Storing a reference beyond the provider's lifetime also dangles, even when the type compiled cleanly.
#include <iostream>
void add_bonus(int& score, int bonus)
{
score += bonus;
}
int main()
{
int score{80};
add_bonus(score, 5);
std::cout << score << '\n';
}Pointers can represent no object
A pointer stores an address or nullptr. Dereferencing with * accesses the pointed-to object, so a nullable pointer must be checked first. Taking an address with &object does not transfer ownership.
Pointer arithmetic is valid only within carefully defined array ranges and is rarely needed in beginner application code. Standard containers, iterators, spans, and algorithms express most sequence work more safely.
Const has more than one position
const int* pointer points to an int that cannot be modified through that pointer. int* const pointer is a pointer value that cannot be reseated. const int* const applies both restrictions. Read declarations from the name outward and use aliases when a type becomes difficult to read.
Const correctness makes interfaces more useful: a function accepting const Widget& can receive both const and non-const objects. It also prevents accidental mutation close to the code that would perform it.
Quick knowledge check
Answer before you reveal.
01Does a raw pointer own the object it points to?
Not by itself. Ownership must come from another explicit contract.
02Why is returning &local invalid?
The local object's lifetime ends when the function returns, leaving a dangling pointer.
Exercise
Practice challenge
Write find_first_even that accepts a const vector reference and returns a pointer to the first even element or nullptr. Check the result before use.
Requirements
- The vector is not copied or modified
- Empty and all-odd vectors return nullptr
- The caller checks before dereferencing
Optional extension: Explain when the returned pointer becomes invalid after vector mutation.
Open in C++ compilerLesson checkpoint
One small step locks it in
Mark this lesson complete, then keep the momentum going.
Clear up the details
Frequently asked questions
Is a reference implemented as a pointer?
The implementation may use an address, but the language semantics differ: a reference must bind and is used as an alias.
Should every optional result be a pointer?
No. std::optional is often clearer for an optional value; a pointer fits optional access to an existing object.
Is nullptr the same as 0?
nullptr is the dedicated null pointer literal and avoids overload ambiguity associated with integer zero.