/compare/cpp/pointer-vs-reference
C++ pointer vs reference: when to use T* or T&
The commands on this page have not been executed by our verification runner yet.updated
- tool
- C++
- compares
- pointer (T*) vs reference (T&)
A C++ reference (T&) is an alias for an existing object: it must be initialized, cannot be null in valid code and cannot be changed to refer to another object. A pointer (T*) holds an address: it can be null, can be reassigned, supports arithmetic, and needs * or -> to reach the object. Use a reference when there is always exactly one object (most function parameters); use a pointer when "no object" is a valid case or the target changes; use smart pointers (std::unique_ptr, std::shared_ptr) when the code owns the object.
Differences
| Pointer T* | Reference T& | |
|---|---|---|
| Can be null | Yes (nullptr) | No |
| Must be initialized | No (but should be) | Yes |
| Can be reseated | Yes, p = &other | No: assignment changes the referred object |
| Access syntax | *p, p->member | r, r.member |
| Arithmetic | Yes (p + 1, p[i]) | No |
| Pointer to it / array of them | Yes | No arrays of references |
| Ownership | Raw pointers should not own; use smart pointers | Never owns |
Example
#include <iostream>
#include <string>
void set_name(std::string& s) { s = "grace"; } // must get an object
void maybe_set_name(std::string* s) { if (s) *s = "linus"; } // may get nullptr
std::size_t length(const std::string& s) { return s.size(); } // read-only, no copy
int main() {
std::string name = "ada";
set_name(name);
maybe_set_name(&name);
maybe_set_name(nullptr);
std::string other = "ken";
std::string& r = name;
r = other; // copies "ken" into name; r still refers to name
std::string* p = &name;
p = &other; // p now points to other
std::cout << name << ' ' << *p << ' ' << length(name) << '\n'; // ken ken 3
}Guidelines for parameters
const T&for inputs that are expensive to copy; plainTfor cheap types such asintorstd::string_view.T&for parameters the function modifies.T*when the argument is optional (nullptrmeans "none"), or usestd::optional<std::reference_wrapper<T>>if you prefer to be explicit.std::unique_ptr<T>by value to transfer ownership; neverdeletean object you received as a raw pointer or reference.
Sources
Related pages
errors · cppC++ error: no matching function for call toNo candidate function, constructor or template accepts the argument types you passed. Read the candidate notes, then fix the arguments, overloads or types.errors · cppC++ error: 'x' was not declared in this scopeGCC cannot find the name at that point: a missing #include, a missing std:: prefix, a function used before its declaration, or a variable outside its block.compare · cmalloc vs calloc in C: zeroed memory and overflow checksmalloc leaves memory uninitialized; calloc zeroes it and fails safely when count times size overflows. Differences, cost, and when to use each in C programs.