A reference, declared with &, is an alias for an existing object — using the reference IS using the original variable, with no separate storage or indirection visible at the language level the way a pointer has. A reference must be initialized at the point of declaration and can never afterward be made to refer to a different object; assigning to a reference assigns to whatever it refers to, not to the reference itself. This makes references simpler and safer than pointers for the common case of "pass this existing object without copying it," which is why modern C++ style favors references over pointers wherever reseating and nullability genuinely aren't needed.
A basic reference: a true alias
ref isn't a separate variable holding x's address — it IS x, under another name; modifying ref modifies x directly, and there's no way to make ref refer to a different variable afterward.
int x = 5;
int& ref = x; // ref is an ALIAS for x, not a separate variable
ref = 10;
std::cout << x << "\n"; // 10 — modifying ref modified x directly
// int& ref2; // COMPILE ERROR: a reference must be initialized immediatelyReferences as function parameters: avoiding a copy
Passing by const reference avoids copying a potentially large object while still preventing the function from modifying the caller's original — this is the idiomatic C++ way to pass anything larger than a primitive type without unnecessary copying.
void modify(int& n) { // reference: modifies the CALLER's variable
n = n * 2;
}
void printLarge(const std::string& s) { // const reference: no copy, no modification allowed
std::cout << s << "\n";
}
int x = 5;
modify(x);
std::cout << x << "\n"; // 10 — x was genuinely modified through the referenceReferences vs pointers: a quick comparison
References are strictly simpler for the common case; pointers remain necessary specifically when reseating or the possibility of "no value" (nullptr) is genuinely part of the design.
int a = 1, b = 2;
int& ref = a;
// ref = b; // this ASSIGNS b's value to a — does NOT reseat ref to point at b
int* ptr = &a;
ptr = &b; // pointers CAN be reseated to point somewhere else — genuinely different
int* maybeNull = nullptr; // pointers can be null
// int& invalidRef = nullptr; // COMPILE ERROR: references cannot be null