Summary
In this post, I will discuss when to use References and when to use Pointers in C++.
Conclusion
As usual, I present the conclusion first.
1. If the varible can be nullptr
, declare the varible as a pointer;
2. If the you want to re-assign the varible, declare the varible as a pointer;
3. Otherwise, use references.
Details
I come across this question when learning the compiler course. Pointers make things complicated when designing compilers in C. And in C++ it becomes more complex after references are introduced.
Why C++ use pointers?
- For compatibility issue, we know pointers are inherited from C.
- In some situations (see the above conclusion), pointers are irreplaceable.
Why introduce references?
Direct reason that references were introduced in C++ is to support operator overloading.
void f1(const complex* x, const complex* y) // without references {
complex z = *x+*y; // ugly
// ...
}
void f2(const complex& x, const complex& y) // with references {
complex z = x+y; // better
// ...
}
Can referent be a nullptr
?
No. Although some compilers will not report it. It’s still illegal. “The C++ language, as defined by the C++ standard, says it’s illegal.”
Foo &foo_ref = *foo_pointer;
cout << foo_ref.bar << endl; // Process finished with exit code 11
How to reset a reference variable to another referent?
No way. Once a reference is bound to an referent, it can not be “reseated” to another referent. The reference isn’t a separate object and the reference is its referent. In that sense, a reference is similar to a const pointer such as int* const p (as opposed to a pointer to const such as const int* p).
See the following example to fully understand it.
class Foo {
public:
int bar;
explicit Foo(int x){
bar = x;
};
};
int main() {
Foo foo1(1);
Foo foo2(2);
Foo &foo_ref = foo1;
cout << foo1.bar << endl; //1
cout << foo2.bar << endl; //2
cout << foo_ref.bar << endl; //1
foo_ref = foo2; //Actually foo1 is a new copy of foo2 now
cout << foo1.bar << endl; //2
cout << foo2.bar << endl; //2
cout << foo_ref.bar << endl; //2
}