Why Use References
beginner
c++11
memory
Related: What Are References and Why Use Pointers
References have many uses in C++ some of which include:
- Avoiding copies when passing arguments
- They can make your syntax cleaner when compared to pointers
Avoiding Copies with References
By default, variables in C++ are copied when they are passed to functions. The same is true for structs, classes, and objects of all sizes. For example, while you might expect the function below to remove 2 of Johnny’s bones and change his name, it does not.
#include <iostream> #include <string> struct Skeleton { std::string name; int bones; }; void remove_two_bones(Skeleton s) { s.name += " the Lesser"; s.bones -= 2; } int main() { Skeleton johnny{"Johnny", 206}; remove_two_bones(johnny); std::cout << johnny.name << " has " << johnny.bones << " bones.\n"; }
Johnny has 206 bones.
When our Skeleton jonny
from main
was passed to the function remove_two_bones
all of the values of Johnny were copied into the function’s parameter s
. This is one of the primary uses of references in C++, to avoid copying data. We can pass a reference to something instead of the thing itself.
#include <iostream> #include <string> struct Skeleton { std::string name; int bones; }; void remove_two_bones(Skeleton& s) { s.name += " the Lesser"; s.bones -= 2; } int main() { Skeleton johnny{"Johnny", 206}; remove_two_bones(johnny); std::cout << johnny.name << " has " << johnny.bones << " bones.\n"; }
Johnny the Lesser has 204 bones.
The syntax for a reference is quite simple.
You take the type of the variable (such as Skeleton
) and you add an ampersand (&
) after that type such as with (Skeleton&
).
When we do this we have a “Skeleton reference” which is a single type, not two things.
You can of course have a constant (const
) reference, which is only for reading data, not writing data, but nonetheless is used very frequently across C++.
#include <iostream> #include <string> struct Skeleton { std::string name; int bones; }; void remove_two_bones(Skeleton& s) { s.name += " the Lesser"; s.bones -= 2; } void describe_skeleton(const Skeleton& s) { std::cout << s.name << " has " << s.bones << " bones.\n"; } int main() { Skeleton johnny{"Johnny", 206}; describe_skeleton(johnny); remove_two_bones(johnny); describe_skeleton(johnny); }
Johnny has 206 bones. Johnny the Lesser has 204 bones.
Cleaner Syntax
References are aliases or “other names” for variables in your program. Because references are simply new names for existing variables C++ treats them exactly as if they were those variables when compiling your code. That means math operations directly apply to the reference as normal and assignment assigns to the reference as you might expect. Here’s some examples:
#include <iostream> int main() { int i = 0; // iAlias is another name for the variable "i" int& iAlias = i; iAlias = iAlias + 2; std::cout << i << "\n"; iAlias = iAlias * 6; std::cout << i << "\n"; iAlias = 42; std::cout << i << "\n"; }
2 12 42