Const references
In the lesson on parameters, a function got either a photocopy of the argument or the original itself. Copying an int or a double is cheap, so such parameters are passed by value. But an object may hold thousands of values, a long text for example. Copying such an object on every call is expensive: it is like photocopying a whole book so a colleague can read one page of it.
Handing over the original is faster, but then the function can spoil it. A third way is needed: hand over the original under the glass of a museum case. You can read it, but you cannot change it.
A read-only reference
A parameter the function only reads is declared as a const reference: const T&, with the parameter's type written in place of T. For int it is const int&:
#include <iostream>
void show(const int& x) {
std::cout << x << '\n';
}
int main() {
int n = 7;
show(n); // 7
show(5); // 5
}Let's walk through both calls:
show(n):xbecomes another name forn, there is no copy, and the function prints7.show(5): a plainint&reference does not accept a number, but a const one does. The function will not change5anyway, so the compiler allows the call, and it prints5.
If you write ++x inside show, the program does not compile. The compiler answers: cannot assign to variable 'x' with const-qualified type 'const int &'. The glass case works: the original can only be read.
For an int, a const reference gains nothing, since copying one number costs nothing. It is written for large objects, and int here only shows the rules.
Common mistake
A function returns a reference to its own local variable:
const int& sum(int a, int b) {
int result = a + b;
return result; // ✗
}warning: reference to stack memory associated with local variable 'result' returned [-Wreturn-stack-address]The compiler only warns, but result is destroyed when the function returns, and the reference is left without a variable. It is like a museum case whose exhibit has been carried off: the glass is still there, and there is nothing under it.
Such a reference is called dangling, and reading through it is undefined behavior. The C++ standard does not define what the program then does, and no result can be relied on.
Return the result by value: int sum(int a, int b). Then the caller gets a copy of the number, and losing result does not hurt it.
Key points
- A const reference
const T&passes an object without a copy and forbids the function to change it. - A
const int¶meter accepts both a variable and a number such as5. - A dangling reference refers to a variable that has already been destroyed; reading through it is undefined behavior.
- Do not return a reference to a local variable: return the result by value.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.