C++ Tutorial
C++ References
A reference is another name for an existing variable. Use it to pass objects without copying.
Another name for the same object
A reference does not store a second copy. It is an alias: one more name glued to a variable that already exists. If r refers to x, then r = 8 changes x. There is only one integer in memory.
You write the type, an ampersand, the new name, and you bind it on the spot:int& r = x;. The ampersand here is not “address of”. In a type, & means reference.
Bind a reference
A reference must be initialized. There is no empty reference waiting to be aimed later. After the bind, every use of r is a use of x.
Example
#include <iostream>
using namespace std;
int main() {
int x = 5;
int& r = x;
cout << r << endl;
r = 8;
cout << x << endl;
x = 1;
cout << r << endl;
return 0;
}The program prints 5, then 8, then 1. r never held its own number. It was always x under a shorter name.
Copy versus reference
Assignment without & copies. int y = x; makes a second integer. Changingy leaves x alone. That is usually what you want for a small number. It is wasteful for a large struct you only need to inspect or update in place.
Example
#include <iostream>
using namespace std;
int main() {
int x = 10;
int copy = x;
int& alias = x;
copy = 99;
alias = 3;
cout << "x: " << x << endl;
cout << "copy: " << copy << endl;
cout << "alias: " << alias << endl;
return 0;
}After this runs, x and alias are both 3. copy is still99. Draw that picture once and references stop feeling like magic.
Swap through references
A function that takes int& parameters works on the caller’s variables. That is how a swap can exchange two numbers without returning a pair. The next chapters cover functions in more detail. The& on the parameters is the same alias rule you just used on r.
Example
#include <iostream>
using namespace std;
void swapInts(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
int main() {
int left = 4;
int right = 9;
swapInts(left, right);
cout << left << " " << right << endl;
return 0;
}a is another name for left. b is another name for right. After the swap, main prints 9 4. If the parameters were plain int, the function would swap two copies and main would still print 4 9.
Rules that keep references simple
- A reference binds to an existing object. You cannot write
int& r;with no initializer. - Once bound, it stays bound. You do not retarget a reference to a different variable.
- Use a reference to share. Use a plain value to copy.
- For a value you will not change, a later habit is
const int&. That is still an alias, but assignment through it is forbidden.
In an expression, &x takes the address of x and produces a pointer. In a type,int& declares a reference. Same character, two jobs. The next chapter is the pointer job.
When to reach for a reference
Pass a struct or a string by reference when the function should update it, or when copying would be pointless work. Pass a small int by value unless you need to change the caller’s variable, as swap does.
References cannot be null. If you need “maybe no object”, that is a pointer, and you must check it. Next: store an address with * and &.
Worked examples
The short listings above are there so you can see the grammar. The programs here use the same statements on quantities that already have units: a speed, a pH, a count of bases. They are classroom numbers. Air resistance is ignored. g is 9.81 m/s² unless a line says otherwise.
Open them in the C++ editor at /cpp/try. Change one measurement and check whether the result still has the right unit.
Physics
Scale a velocity in place
A reference is another name for the same object. Doubling speed through alias writes back into speed. After the line, the original variable is 10 m/s, not a copy that got thrown away.
v′ = 2v
Example
#include <iostream>
using namespace std;
int main() {
double speed = 5.0;
double &alias = speed;
alias = alias * 2.0;
cout << "speed = " << speed << " m/s" << endl;
return 0;
}Maths
Swap two side lengths
A 6 by 9 rectangle has the same area after you swap width and height. swap(a, b) takes references. Passing copies would swap locals and leave the originals alone.
Example
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
double width = 6.0;
double height = 9.0;
swap(width, height);
cout << width << " by " << height << endl;
return 0;
}