C++ PROGRAMMING ยท 16 MIN STUDY

References and const references

Understand references as aliases, pass values efficiently, and compare references with pointers.

Learning objectives

  • Explain a reference as an alias for an existing object.
  • Pass an object by reference to allow a function to modify it.
  • Use a const reference for read-only access.
  • Compare references and pointers.

Prerequisites: functions, variables, pointers, and object lifetime at a basic level. Review the pointer lesson if address and dereference syntax is unfamiliar.

What is a reference?

A reference is another name for an existing object. It is declared with & after the type and must be initialized when it is created.

int score{10};
int& alias{score};
alias = 25;
// score is now 25

The reference does not create a second independent integer. Both names refer to the same object.

Pass by value: function gets a copy

C++17
void add_one(int value) {
    value += 1;
}
int main() {
    int score{10};
    add_one(score);
    // score is still 10
}

The parameter value is a separate object initialized from the argument. Changing it does not change the caller's score.

Pass by reference: function works with caller's object

C++17
void add_one(int& value) {
    value += 1;
}
int main() {
    int score{10};
    add_one(score);
    // score is now 11
}

The int& parameter is a reference to the caller's integer. The assignment changes the original object.

Pass by const reference: read without copying

C++17
#include <iostream>
#include <string>

void greet(const std::string& name) {
    std::cout << "Hello, " << name << '\n';
    // name += "!"; // error: read-only through this reference
}

A const std::string& allows the function to read the caller's string without making a string copy, and prevents this function from modifying it through that parameter. This is a common interface for read-only access to larger objects.

Reference and pointer comparison

ReferencePointer
Must be initializedCan be initialized to nullptr
Acts as an alias to an objectStores an address
Cannot be reseated to refer to another objectCan be assigned a different address
Used directly like the referred objectMust be dereferenced with * to access the pointed-to object

Important lifetime rule

A reference must not outlive the object it refers to. Returning a reference to a local variable is a bug because that local object is destroyed when the function returns.

int& broken() {
    int local{5};
    return local; // WRONG: reference dangles after return
}

Return by value for ordinary small results. Modern C++ can efficiently return objects by value, so do not use references just to avoid every copy.

Common mistakes

  • Declaring a reference without initializing it.
  • Expecting a reference to be reseated by assigning another object to it.
  • Returning a reference to a local variable.
  • Using a non-const reference when the function should only read its argument.
  • Assuming pass-by-reference automatically transfers ownership. It does not.

Practice

  1. Write void reset(int& value) that sets the caller's integer to zero.
  2. Write a function that prints a const std::string& without modifying it.
  3. Predict the values after one pass-by-value call and one pass-by-reference call.
  4. Explain why returning a reference to a local variable is unsafe.

Practice solutions

Show worked solutions
  1. void reset(int& value) {
        value = 0;
    }
    The reference parameter aliases the caller's integer.
  2. #include <iostream>
    #include <string>
    void print_text(const std::string& text) {
        std::cout << text << '\n';
    }
    The const reference avoids a string copy and prevents modification through this parameter.
  3. A pass-by-value function changes only its local copy. A pass-by-reference function can change the caller's original object. Trace the assignments in each function to see which object is modified.
  4. A local automatic object is destroyed when its function returns. A reference to it would then refer to an object whose lifetime has ended; using that reference is undefined behavior.

Check your understanding

Does int& r = x; create a second integer?

Answer: No. It creates a reference name for the existing object x.

Summary

Use references when a function needs an existing object, use non-const references when it should modify that object, and use const references for read-only access. Never let a reference outlive the object it refers to.

References