When should I use a reference and when should I use a pointer?
Both references and pointers allow you to create a variable that refers to something else but there are differences. You can’t just prefer one over the other. That would be like a carpenter preferring to use a hammer over a saw. They each have their uses and you should know when and how to use each one.
A good way to summarize the two concepts is this:
- A reference creates a new name for an existing variable. You don’t actually get a second variable with a reference. The compiler will keep track of the variable that the reference refers to.
- And a pointer creates a variable that points to another variable or to nothing. This does give you a new variable because you need someplace to remember where the pointer points.
Between the two types, only the pointer can point to nothing. A reference should always refer to a valid variable. There are ways to cause a reference to be invalid and they’re a good way to crash your application. With a pointer, you don’t have to assign it to point to anything now or ever. It can remain pointing to null if you want. This brings up an important usage of pointers. Use them when you have the possibility that some value might not exist. Maybe you want an optional method parameter. You either need a pointer for that or use another concept called a nullable value.
The flip side is that you should use a reference when you want to show that a value should exist. You’ll normally find references in method parameters because they let a method refer directly to the value that’s passed to the method. In other words, a reference gives the method its own name for your variable that was used to call the method. This lets the method modify your value directly.
If you don’t want that, then declare the reference in the method parameter to be const. This gives you the ability to call a method using your variable directly without needing to make a copy of your variable for its own use and still maintain some amount of confidence that the method won’t change the value of your variable.
You normally use references for classes or structs passed to methods to improve the efficiency of the code because otherwise, the compiler will create a copy of your class or struct variable before calling the method.
Now that you know how references are often used, why would you want to use a pointer? I’ve already mentioned that pointers can point to nothing. But probably the biggest use of pointers is for keeping track of memory that’s been dynamically allocated. This is where you ask for some memory to create a new variable instead of declaring the variable as a local method variable which will put it on the stack.
If you have a method that creates some class instance for you and gets it all setup and ready to use, then the method needs to return that object so you can then use it. This is where you should use dynamic memory. Anything that the method puts on the stack will get destroyed when the method returns. By returning a pointer to where you created the object in the main memory, then the calling code can continue to use that object long after the method has returned. A pointer also signals to the calling code that it owns the object and needs to delete it when done.
If you’re calling a method that returns a pointer to you that you then need to make sure gets deleted, then use one of the smart pointer classes. You can use a shared_ptr if you want to then be able to pass that pointer to other places in your code and have them all make use of it. And you can use a unique_ptr when you want to make sole use of the returned object. Using one of the smart pointers will make sure that delete gets called even if an exception is thrown.
Another common usage of pointers is when you want one variable to point to something, then something else, then another etc. You can’t do this with a reference because you can only assign the variable the reference works with once right when the reference is first created.