A pointer can be re-assigned:
Copyint x = 5; int y = 6; int *p; p = &x; p = &y; *p = 10; assert(x == 5); assert(y == 10);A reference cannot be re-bound, and must be bound at initialization:
Copyint x = 5; int y = 6; int &q; // error int &r = x;A pointer variable has its own identity: a distinct, visible memory address that can be taken with the unary
&operator and a certain amount of space that can be measured with thesizeofoperator. Using those operators on a reference returns a value corresponding to whatever the reference is bound to; the reference’s own address and size are invisible. Since the reference assumes the identity of the original variable in this way, it is convenient to think of a reference as another name for the same variable.Copyint x = 0; int &r = x; int *p = &x; int *p2 = &r; assert(p == p2); // &x == &r assert(&p != &p2);It is possible to create a pointer to a pointer, but not a pointer to a reference.
Copyint **pp; // OK, pointer to pointer int &*pr; // ill-formed, pointer to referenceIt is possible to create an array of pointers, but not an array of references.
Copyint *ap[]; // OK, array of pointers int &ar[]; // ill-formed, array of referencesYou can have arbitrarily nested pointers to pointers offering extra levels of indirection. References only offer one level of indirection because references to references collapse.
Copyint x = 0; int y = 0; int *p = &x; int *q = &y; int **pp = &p; **pp = 2; pp = &q; // *pp is now q **pp = 4; assert(y == 4); assert(x == 2);A pointer can be assigned
nullptr, whereas a reference must be bound to an existing object. If you try hard enough, you can bind a reference tonullptr, but this is undefined and will not behave consistently.Copy/* the code below is undefined; your compiler may optimise it * differently, emit warnings, or outright refuse to compile it */ int &r = *static_cast<int *>(nullptr); // prints "null" under GCC 10 std::cout << (&r != nullptr ? "not null" : "null") << std::endl; bool f(int &r) { return &r != nullptr; } // prints "not null" under GCC 10 std::cout << (f(*static_cast<int *>(nullptr)) ? "not null" : "null") << std::endl;You can, however, have a reference to a pointer whose value is
nullptr.Pointers are ContiguousIterators (of an array). You can use
++to go to the next item that a pointer is pointing to, and+ 4to go to the 5th element.A pointer needs to be dereferenced with
*to access the object it points to, whereas a reference can be used directly. A pointer to a class/struct uses->to access its members whereas a reference uses a..Const references and rvalue references can be bound to temporaries (see temporary materialization). Pointers cannot (not without some indirection):
Copyconst int &x = int(12); // legal C++ int *y = &int(12); // illegal to take the address of a temporary.This makes
const &more convenient to use in argument lists and so forth.
c++ - What are the differences between a pointer variable and a reference variable? - Stack Overflow
When to use pointers and references? - C++ Forum
c++ - Reference vs. pointer - Stack Overflow
I am absolutely confused on the topic of references vs pointers
When should I use a reference vs a pointer in C++?
What is the difference between a reference and a pointer in C++?
Can a C++ reference be null?
Videos
On one hand, there is the Brief Introduction To C++’s Model For Type- And Resource-Safety which is considered to be an authoritative source for the obvious reason that Bjarne Stroustrup himself co-authored it, and it says :
"A reference is a restricted form of a pointer with some added syntactic sugar, so our techniques for pointers also deal with references."
On the other hand, there is the C++ FAQ which is also considered to be an authoritative source, and it says this about references:
"Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object, just with another name. It is neither a pointer to the object, nor a copy of the object. It is the object. There is no C++ syntax that lets you operate on the reference itself separate from the object to which it refers."
To me, it appears that these statements contradict each other, or do they? I don't know anymore. Could someone enlighten me and for once and for all, define exactly what a reference is, and what's the difference between that and a pointer? Thanks.
A pointer can be re-assigned:
Copyint x = 5; int y = 6; int *p; p = &x; p = &y; *p = 10; assert(x == 5); assert(y == 10);A reference cannot be re-bound, and must be bound at initialization:
Copyint x = 5; int y = 6; int &q; // error int &r = x;A pointer variable has its own identity: a distinct, visible memory address that can be taken with the unary
&operator and a certain amount of space that can be measured with thesizeofoperator. Using those operators on a reference returns a value corresponding to whatever the reference is bound to; the reference’s own address and size are invisible. Since the reference assumes the identity of the original variable in this way, it is convenient to think of a reference as another name for the same variable.Copyint x = 0; int &r = x; int *p = &x; int *p2 = &r; assert(p == p2); // &x == &r assert(&p != &p2);It is possible to create a pointer to a pointer, but not a pointer to a reference.
Copyint **pp; // OK, pointer to pointer int &*pr; // ill-formed, pointer to referenceIt is possible to create an array of pointers, but not an array of references.
Copyint *ap[]; // OK, array of pointers int &ar[]; // ill-formed, array of referencesYou can have arbitrarily nested pointers to pointers offering extra levels of indirection. References only offer one level of indirection because references to references collapse.
Copyint x = 0; int y = 0; int *p = &x; int *q = &y; int **pp = &p; **pp = 2; pp = &q; // *pp is now q **pp = 4; assert(y == 4); assert(x == 2);A pointer can be assigned
nullptr, whereas a reference must be bound to an existing object. If you try hard enough, you can bind a reference tonullptr, but this is undefined and will not behave consistently.Copy/* the code below is undefined; your compiler may optimise it * differently, emit warnings, or outright refuse to compile it */ int &r = *static_cast<int *>(nullptr); // prints "null" under GCC 10 std::cout << (&r != nullptr ? "not null" : "null") << std::endl; bool f(int &r) { return &r != nullptr; } // prints "not null" under GCC 10 std::cout << (f(*static_cast<int *>(nullptr)) ? "not null" : "null") << std::endl;You can, however, have a reference to a pointer whose value is
nullptr.Pointers are ContiguousIterators (of an array). You can use
++to go to the next item that a pointer is pointing to, and+ 4to go to the 5th element.A pointer needs to be dereferenced with
*to access the object it points to, whereas a reference can be used directly. A pointer to a class/struct uses->to access its members whereas a reference uses a..Const references and rvalue references can be bound to temporaries (see temporary materialization). Pointers cannot (not without some indirection):
Copyconst int &x = int(12); // legal C++ int *y = &int(12); // illegal to take the address of a temporary.This makes
const &more convenient to use in argument lists and so forth.
What's a C++ reference (for C programmers)
A reference can be thought of as a constant pointer (not to be confused with a pointer to a constant value!) with automatic indirection, ie the compiler will apply the * operator for you.
All references must be initialized with a non-null value or compilation will fail. It's neither possible to get the address of a reference - the address operator will return the address of the referenced value instead - nor is it possible to do arithmetics on references.
C programmers might dislike C++ references as it will no longer be obvious when indirection happens or if an argument gets passed by value or by pointer without looking at function signatures.
C++ programmers might dislike using pointers as they are considered unsafe - although references aren't really any safer than constant pointers except in the most trivial cases - lack the convenience of automatic indirection and carry a different semantic connotation.
Consider the following statement from the C++ FAQ:
Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object. It is not a pointer to the object, nor a copy of the object. It is the object.
But if a reference really were the object, how could there be dangling references? In unmanaged languages, it's impossible for references to be any 'safer' than pointers - there generally just isn't a way to reliably alias values across scope boundaries!
Why I consider C++ references useful
Coming from a C background, C++ references may look like a somewhat silly concept, but one should still use them instead of pointers where possible: Automatic indirection is convenient, and references become especially useful when dealing with RAII - but not because of any perceived safety advantage, but rather because they make writing idiomatic code less awkward.
RAII is one of the central concepts of C++, but it interacts non-trivially with copying semantics. Passing objects by reference avoids these issues as no copying is involved. If references were not present in the language, you'd have to use pointers instead, which are more cumbersome to use, thus violating the language design principle that the best-practice solution should be easier than the alternatives.
In this case, they are equivalent.
It does not matter which you use, and neither is "best".
If you really want to choose between them then the reference is probably more idiomatic. I generally stick to references wherever I can because my OCD likes it: they feel "tighter", cannot be re-bound (with or without you noticing) and don't require a dereference to get to the value.
But I'm not aware of any general consensus on the issue for cases such as this.
Also note that the two may not compile to the same code if your implementation does not implement references with pointers, though I know of no implementation like that, and you wouldn't notice the difference anyway.
A pointer is the address of the memory location. You can change the value of that address to point at different memory addresses.
A reference is an alias of the variable. You can only assign this alias during declaration. You cannot change which variable the reference is an alias of after it's declared.
The following pointer assignments are not possible with references.
int a = 10;
int b = 20;
int* pInt = NULL; // A pointer pointing at nothing.
pInt = &a; // pInt now points at a
pInt = &b; // pInt now points at b
As for which one is better, it all depends on context.
I use references for method and function parameters.
void updateFoo(Foo& foo)
I use references to alias complex objects.
Foo& foo = bar.getBaz().getFoo(); // easy access to foo
I use pointers for dynamically allocated objects.
Foo* pFoo = new Foo();
I use pointers for things which may point at different values (including no value at all).
Foo* pFoo = NULL;
if (condition1)
pFoo = &foo1;
else (condition2)
pFoo = &foo2;
As a general rule, I default to references and use pointers in places where the limitations on references cause problems.