Introduction
Functions normally work on copies. That is safe, but sometimes a function has to change the caller's variable, and copying a list of a million items on every call would be very wasteful. References solve both problems, and they appear in almost every real C++ program.
How it works
A reference is a second name for a variable that already exists. It is written with & after the type:
int x = 5;
int& r = x;
r = 9; // x is now 9
A reference has to be connected to something when it is made, and it stays with that variable for life.
As parameters. With a plain int parameter, the function gets a copy. With int&, the parameter is another name for the caller's variable, so changes are seen by the caller.
Const references. Passing a vector or string by value copies every element. Passing by const vector<int>& costs almost nothing, and const guarantees that the function will not change it. This is the normal way of passing anything larger than a number.
In loops. for (int& x : v) makes x a reference to each element, so changing x changes the vector. Without the &, x is a copy.
| You want | Write |
|---|---|
| a small value, read only | int x |
| to change the caller's variable | int& x |
| a large value, read only | const string& s |
#include <iostream>
#include <vector>
using namespace std;
int total(const vector<int>& v) {
int sum = 0;
for (int x : v) {
sum += x;
}
return sum;
}
void add_to_all(vector<int>& v, int amount) {
for (int& x : v) {
x += amount;
}
}
int main() {
vector<int> v = {1, 2, 3};
cout << total(v) << endl;
add_to_all(v, 10);
cout << total(v) << endl;
return 0;
}Syntax
void reset(int& n) {
n = 0;
}
int length(const string& s) {
return s.size();
}
Example
#include <iostream>
using namespace std;
void swap_values(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 4, y = 9;
swap_values(x, y);
cout << x << " " << y << endl;
return 0;
}Line by line
aandbare references, so they are other names for the caller's variables.int temp = a;saves the first value.a = b;andb = temp;changexandydirectly.mainpassesxandywith no special syntax.- The values have been swapped when they are printed.
Expected result
9 4
In the real world
Passing by const& is one of the first things reviewers look for in C++ code, because needless copies are a common cause of slow programs. Standard library functions take most of their arguments this way.
Common mistakes
- Forgetting the
&, so the function changes only a copy. - Forgetting the
&in a loop, so that changes are lost. - Returning a reference to a local variable, which no longer exists after the return.
- Passing a large object by value when only reading it.
Best practices
- Pass numbers and other small values by value.
- Pass larger read-only objects by
const&. - Use a plain reference only when the function really needs to change the value.
Summary
A reference is another name for a variable. Reference parameters let functions change their caller's variables, and const& passes large values with no copying. In a range-based loop, & lets you change the elements.
Quick check
Key takeaways
- A reference is another name for the same variable.
- Use a plain reference when a function must change something.
- Use const& to read a large object without copying it.
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.