CS 70

const References

  • LHS Cow speaking

    Remember the constexpr qualifier?

  • Cat speaking

    Sure, that means that a variable's value is known at compile time and can never change.

  • LHS Cow speaking

    We are going to introduce another, very similar qualifier: const.

The const Qualifier

When a variable is const, its value can't change.

Unlike constexpr, a const variable's value doesn't need to be known at compile time.

For example, this code is totally legal:

cout << "Enter a number: ";
int x;
cin >> x;
const int y = x;

Obviously, y's value can't be known at compile time, but we've still promised not to change its value.

  • Bjarne speaking

    In a lot of ways, it makes sense to pronounce const as “read-only”.

Read-Only (const) References

The ability to make variables whose values can't change has limited uses.

Things get much more interesting when references get involved!

Using the const qualifier, we can create read-only references that can't be used to change the value of their referent.

For example,

int a = 3;
const int& b = a;
++b;
cout << a << " " << b;

Based on the diagram in the video, what is the printed output of this snippet?

int a = 3;
const int& b = a;
++a;
cout << a << " " << b;

Based on the diagram in the video, what is the printed output of this snippet?

Key Idea: The const keyword affects access through that name, but it does not change access through any other names.

  • LHS Cow speaking

    You can totally make a const reference to a non-const variable.

  • Cat speaking

    This makes sense when we think of const as “read-only access”; just because we only have read access doesn't mean everyone does.

  • Duck speaking

    How about creating a non-const reference to something that's const?

  • LHS Cow speaking

    No! If you could, you could get around the const qualifier just by making a reference!

Important Rule: You cannot make a non-const reference to a const variable.

  • LHS Cow speaking

    So these examples are all okay:

int c = 5;
int& d = c;

const int e = 10;
const int& f = e;

int g = 3;
const int& h = g;
  • RHS Cow speaking

    But this code would cause a compiler error:

const int i = 9;
int& j = i; // Causes a compiler error!
  • LHS Cow speaking

    In our diagram we can imagine that the padlock always has to come along for the ride when we make a reference.

One analogy that might make it easier to remember how const works with references, is to think about consts like the permissions for a Google document.

Imagine that Alice starts a new Google document.
int a = 5;
Then Alice invites Bob to be an editor.
int& b = a;
They can both see and make changes to the same document.
b = 21;
cout << a << endl; // Prints 21
a = 42;
cout << b << endl; // Prints 42
Now Bob invites Carol to be a viewer.
const int& c = b;
Carol can see the document, but not make changes.
cout << c << endl; // Prints 42
//c = 17;          // Would cause a compiler error
If Alice or Bob make changes, Carol sees the changes, because they are all accessing the same document.
a = 84;
cout << c << endl; // Prints 84
If Carol tries to invite Eve to be an editor, she will get an error. Carol can't grant someone else more access than she has! Sorry, Eve! You can't edit this document!
//int& e = c;      // Would cause a compiler error
But Carol can invite Dave to be a viewer!
const int& d = c;
Hooray for Dave!
cout << d << endl; // Prints 84

(When logged in, completion status appears here.)