C++ FAQ says:
“Use references when you can, and pointers when you have to.”
I feel it’s not as easy as stated above. The reasons why references are generally better to pointers have been well discussed. So I would rather like to discuss special cases where references make sense but are highly unusual and just don’t feel right:
To me the most obvious case is their usage in general data structures like a tree or linked-list. Their interfaces could be certainly implemented using references and feel safer, but I haven’t seen a single implementation that would take advantage of references e.g.:
Node *parent = n.parent(); // parent might be unset -> pointer
Node &child = n.child(5); // child is always valid -> reference
Although it might seem attractive, it leads to code like this:
if(parent == &child) ... // weird, unusual at least?
I’m wondering, is this what stands for pure C++?
Each time I’ve tried to blindly use references wherever it’s possible, I’ve encountered all kinds of similar inconsistencies and ended up mixing pointers and references in various ugly ways.
To conclude, why the operator new doesn’t return a reference to a new instance instead of a pointer in the first place? (and throws in case of error):
Node &n = new Node;
delete &n;
It’s an absurd example, but isn’t that what would be “pure C++”?
References are used to refer an existing variable in another name whereas pointers are used to store address of variable. References cannot have a null value assigned but pointer can. A reference variable can be referenced by pass by value whereas a pointer can be referenced but pass by reference.
Pointers save memory space. Execution time with pointers is faster because data are manipulated with the address, that is, direct access to memory location. Memory is accessed efficiently with the pointers. The pointer assigns and releases the memory as well.
In C++, Reference variables are safer than pointers because reference variables must be initialized and they cannot be changed to refer to something else once they are initialized.
Reference variables are cleaner and modish as compare to the pointers; they can also be used while passing in the function as arguments, known as call by references.
A reference cannot be modified to refer to a different object once it is initialized. But a pointer could be modified to refer different objects at run time.
A general rule of thumb
Whenever you want a variable to point to different objects during its life time, use a pointer.
If you just want to use a variable as an alias for another variable use a reference.
As parameters
We sometimes pass parameters as references (const/non-const). This would help in avoiding copying the entire object, every time a function is called. Hence this would make much sense, when passing object of large size.
If the function needs to receive some parameter than can optionally be null, you could use a pointer. But, again, you could always define a static null object for any class, and it can be used.
As return values
Whenever we overload operators such as [] or <<, we would return references. It is because, if I say, vec[0] = 10, it should actually assign the value 10 to position 0 in vec. Here I could not not use pointer for obvious reasons. *vec[0] = 10 won't just look nice. Also, you should guarantee, when you are returning a reference it is always referring to an object (It should never be null).
Again, when the function can return NULL values, use a pointer, otherwise you may have to declare a static null object for that class.
As data members
References should be initialized in the constructor. Hence, they cannot be changed once the object is constructed.
Hence if you need a variable that needs to point to different objects during the lifetime of the class, a pointer would be a good choice.
I think generic data structures fall under the "use pointers when you have to" clause. That is, since references are constant (i.e. they always refer to the same object), using references in your linked list or tree node structure would mean that you couldn't insert new nodes or remove old ones from the data structure--generally defeating the purpose.
As somebody said in the comments, I think that advice really applies to function arguments. Passing references rather than pointers avoids having to add null-pointer handling logic to every function, which brings a host of benefits in terms of code size and clarity.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With