LearnContact
Lesson 169 min read

References

Sometimes, instead of creating another variable with a copy of the value, you may want another name that refers to the same variable. In this lesson, you will learn how C++ uses references to create aliases for existing variables.

Introduction

In the previous lesson, you learned about strings. Now consider a situation where you already have a variable and want another name to access the same variable.

Original Variable
int number = 100;

Normally, creating another variable and assigning number to it creates a separate variable containing a copy of the value.

Creating a Copy
int number = 100;
int anotherNumber = number;

Here, number and anotherNumber are independent variables. Changing one does not automatically change the other.

Sometimes, however, you do not want another copy. You want another name that refers to the original variable itself.

The Solution

C++ provides references, which allow another name to refer to an existing variable.

What is a Reference?

A reference is an alias, or another name, for an existing variable.

A reference does not represent an independent value. Instead, operations performed through the reference affect the original object to which it is bound.

Simple Reference
int number = 100;
int &ref = number;

In this example, number is the original variable and ref is a reference bound to number.

Relationship
number ─────┐
             ├────► Same int object
ref ─────────┘
Simple Definition

A reference is another name through which an existing variable can be accessed.

Why Do We Need References?

References become especially useful when programs work with functions, objects, containers, and large amounts of data.

Without References

  • Large objects may need to be copied.
  • Copying can consume additional time and memory.
  • Functions cannot directly modify the original argument when values are passed by value.
  • Some interfaces become less convenient to use.

With References

  • Avoid unnecessary copying.
  • Allow functions to work with original objects.
  • Improve efficiency for large objects.
  • Provide convenient alias syntax.
  • Support cleaner function interfaces.

Efficiency

Large objects can be accessed without creating unnecessary copies.

Modification

Functions can modify original arguments when passed by reference.

Readability

References often provide cleaner syntax than pointers when nullability and reseating are unnecessary.

Read-Only Access

Const references allow efficient access while preventing modification through the reference.

Real-World Analogy

Imagine one person whose official name is Rahul Sharma. Different people may call the same person Rahul, Raju, or Buddy.

Multiple Names, Same Person
Rahul ───────┐
Raju ─────────┼────► Same Person
Buddy ────────┘

The names are different, but they all refer to the same person. A reference works similarly by providing another name for an existing variable.

Original Variable Exists
Create Another Name
Bind Name to Original Variable
Both Access the Same Object
Alias Concept

A reference does not create a second independent variable. It provides another way to access the original variable.

Characteristics of References

Acts as an Alias

A reference provides another name for an existing variable.

Bound to an Existing Object

A reference must be initialized to refer to a valid object.

Changes Affect the Original

Modifying the object through the reference modifies the original object.

Must Be Initialized

A reference must be bound when it is declared.

Cannot Be Reseated

After initialization, a reference cannot be changed to refer to another object.

Natural Syntax

After declaration, a reference is generally used with normal variable syntax.

Key Characteristics

  • A reference acts as an alias.
  • It refers to an existing object.
  • It must be initialized when declared.
  • Changes through a non-const reference affect the original object.
  • A reference cannot later be reseated to another object.
  • A reference uses normal variable-like syntax after declaration.

Reference Declaration

To declare an lvalue reference, place the & symbol between the data type and the reference name.

Syntax
data_type &reference_name = variable_name;
Example
int number = 100;
int &ref = number;
PartMeaning
intThe type of object being referenced
&Indicates an lvalue reference in this declaration
refThe reference name
numberThe existing variable to which the reference is bound

After the declaration, ref can be used to access the same int object as number.

Using the Reference
std::cout << number;
std::cout << ref;
The Meaning of & Depends on Context

In a declaration such as int &ref = number;, & declares a reference. In an expression such as &number, it is the address-of operator.

Memory Representation

Consider a variable and a reference bound to it.

Reference Example
int number = 100;
int &ref = number;
Conceptual Memory Representation
Names
────────────────────

number ──────┐
             │
ref ─────────┘
             │
             ▼
        ┌─────────┐
        │   100   │
        └─────────┘
          int object

Both names provide access to the same int object. Therefore, changing the value through either name changes the value observed through the other.

Same Address
std::cout << &number << std::endl;
std::cout << &ref;

Taking the address of number and the address of the object accessed through ref produces the same address.

One Object, Two Names

Conceptually, number and ref are two names used to access the same object.

Example 1: Creating a Reference

Example 1
#include <iostream>

int main()
{
    int number = 100;
    int &ref = number;

    std::cout << number << std::endl;
    std::cout << ref;

    return 0;
}

Explanation

  • number is created with the value 100.
  • ref is declared as a reference to number.
  • ref becomes another name for the object accessed through number.
  • Printing number displays 100.
  • Printing ref also displays 100.
Output
100
100
Same Value

Both names display the same value because they access the same object.

Example 2: Modifying Through a Reference

Example 2
#include <iostream>

int main()
{
    int number = 50;
    int &ref = number;

    ref = 80;

    std::cout << number << std::endl;
    std::cout << ref;

    return 0;
}
Create number with 50
Bind ref to number
Assign 80 Through ref
Original Object Becomes 80
Both Names Display 80
Before Modification
number ─────┐
             ├────► 50
ref ─────────┘
After ref = 80
number ─────┐
             ├────► 80
ref ─────────┘
Output
80
80
Modification Affects the Original

Assigning a value through a non-const reference changes the original object to which the reference is bound.

Important Rules for References

References follow several important rules that beginners must understand.

1. Must Be Initialized

A reference must be bound to an object when it is declared.

2. Cannot Be Reseated

After initialization, a reference cannot be changed to refer to another object.

3. Type Must Be Compatible

A non-const lvalue reference must bind to an appropriate object of a compatible type.

4. Assignment Changes the Object

Assigning through a reference changes the referenced object rather than rebinding the reference.

Rule 1: Must Be Initialized
// ❌ Incorrect
int &ref;

// ✅ Correct
int value = 10;
int &ref = value;
Rule 2: References Cannot Be Reseated
int a = 10;
int b = 20;

int &ref = a;

ref = b;

The statement ref = b; does not make ref refer to b. It assigns the value of b to the object already referenced by ref.

Result
Before:
a = 10
b = 20
ref refers to a

After ref = b:
a = 20
b = 20
ref still refers to a
Assignment Is Not Rebinding

Once a reference is initialized, using the assignment operator modifies the referenced object. It does not make the reference refer to another variable.

Program Execution Flow

Program Starts
Create Original Variable
Create Reference
Bind Reference to Variable
Access Same Object Through Either Name
Modify or Display Value
Program Ends

A reference must be connected to an existing object during initialization. After that, the original variable name and the reference can both be used to access that object.

References vs Variables & Pointers

References are easier to understand when compared with ordinary variables and pointers.

References vs Variables

FeatureVariableReference
PurposeRepresents its own objectActs as an alias for an existing object
InitializationMay sometimes be declared without an initializerMust be initialized
IndependenceExists as its own objectDepends on an object to reference
AssignmentChanges its stored valueChanges the referenced object
ReseatingNot applicableCannot be reseated after initialization

References vs Pointers

FeatureReferencePointer
ConceptAlias for an objectObject that stores an address
InitializationMust be initializedCan be default-initialized or explicitly initialized depending on context
Null StateA valid reference is expected to refer to an objectCan hold nullptr
ReseatingCannot be reseatedCan be changed to point elsewhere
Access SyntaxNormal variable syntaxUsually requires dereferencing with *
Address StorageReference semanticsExplicitly stores a memory address value
Reference
int value = 10;
int &ref = value;

ref = 20;
Pointer
int value = 10;
int *ptr = &value;

*ptr = 20;
Main Difference

A reference provides aliasing syntax, while a pointer is an object that stores an address and can be explicitly redirected.

Real-World Applications

Functions

Pass objects efficiently and allow functions to modify original arguments when appropriate.

Object-Oriented Programming

Work efficiently with objects, method parameters, and return values.

Standard Library

Containers, iterators, range-based loops, and algorithms frequently use references.

Game Development

Work with game entities, components, resources, and shared state without unnecessary copies.

Large Data Structures

Access vectors, strings, and custom objects efficiently.

Read-Only Parameters

Const references provide efficient access without allowing modification through the reference.

Passing by Reference
void updateScore(int &score)
{
    score = score + 10;
}
Using the Function
int score = 50;

updateScore(score);

std::cout << score;
Output
60
Functions Are a Major Use Case

References are commonly used in function parameters to avoid copies or to allow a function to work with the caller's original object.

Advantages of References

Avoid Copies

Large objects can be accessed without copying all of their data.

Improve Efficiency

Avoiding unnecessary copies can reduce time and memory overhead.

Clean Syntax

References are used with familiar variable-like syntax.

Modify Original Data

Non-const references allow functions to modify caller-owned objects.

Support Const Access

Const references provide efficient read-only access.

Standard C++ Integration

References are widely used throughout modern C++ and the standard library.

  • Avoid unnecessary copying of large objects.
  • Can improve performance.
  • Can reduce temporary memory usage.
  • Provide convenient syntax.
  • Allow functions to modify original arguments.
  • Support efficient read-only access through const references.
  • Work naturally with objects and standard library facilities.

Common Beginner Mistakes

Forgetting Initialization

A reference must be initialized when it is declared.

Assuming a Reference Is an Independent Copy

A reference is an alias. Changes through it affect the referenced object.

Confusing References with Pointers

References provide aliasing semantics, while pointers explicitly store addresses.

Trying to Reassign a Reference

Assignment through a reference modifies the referenced object instead of reseating the reference.

Returning References to Dead Local Variables

A reference must never be used after the object it refers to has been destroyed.

Forgetting Initialization
// ❌ Incorrect
int &ref;

// ✅ Correct
int value = 10;
int &ref = value;
Reference Is Not a Copy
int number = 10;
int &ref = number;

ref = 50;

std::cout << number;
Output
50
Assignment Does Not Reseat
int a = 10;
int b = 20;

int &ref = a;

ref = b;

// a is now 20.
// ref still refers to a.
Avoid Dangling References

Never keep or return a reference to a local object that has already been destroyed. Such a reference no longer refers to a valid object.

Best Practices

  • Initialize references immediately when they are declared.
  • Use references when aliasing an existing object is appropriate.
  • Use references for function parameters when a function must modify the caller's object.
  • Use const references for large read-only function parameters.
  • Prefer references over pointers when nullability and reseating are not needed.
  • Use pointers when an optional no-object state or reseating is part of the design.
  • Avoid returning references to local variables.
  • Keep the lifetime of the referenced object longer than every reference that uses it.
  • Use clear parameter names that describe the object's purpose.
  • Avoid using references merely to optimize tiny primitive values without a clear reason.
Modify Through Reference
void increase(int &value)
{
    value++;
}
Read Large Object Through Const Reference
void displayName(const std::string &name)
{
    std::cout << name;
}
A Useful Guideline

Use T& when modification is required, const T& for efficient read-only access to suitable objects, and pointers when nullability or reseating is meaningful.

Frequently Asked Questions

What is a reference?

A reference is an alias, or another name, for an existing object.

Does a reference create an independent copy?

No. A reference provides another way to access the object to which it is bound.

Can a reference exist without initialization?

No. A reference must be initialized when it is declared.

Can a reference refer to another variable later?

No. A reference cannot be reseated after initialization.

What happens when I assign through a reference?

The assignment modifies the object to which the reference is already bound.

What is the difference between a reference and a pointer?

A reference acts as an alias, while a pointer is an object that stores an address and can be explicitly redirected.

Why are references used in functions?

They can avoid unnecessary copies and can allow functions to modify original arguments.

What is a const reference?

A const reference provides access to an object without allowing that object to be modified through the reference.

Can two references refer to the same variable?

Yes. Multiple references can be bound to the same object.

What is a dangling reference?

A dangling reference is a reference that refers to an object whose lifetime has already ended.

Key Takeaways

  • A reference is an alias for an existing object.
  • References are declared using & in the declaration.
  • A reference must be initialized when declared.
  • A reference cannot be reseated after initialization.
  • Assignment through a reference modifies the referenced object.
  • References provide convenient variable-like syntax.
  • References are commonly used in function parameters.
  • Non-const references can allow modification of original arguments.
  • Const references can provide efficient read-only access.
  • References and pointers are related concepts but have different syntax and semantics.
  • A reference must not outlive the object to which it refers.
  • References are widely used throughout modern C++.

Summary

References are an important feature of C++ that allow another name to access an existing object.

A reference must be initialized when it is declared and cannot later be reseated to another object. When a non-const reference is used to modify a value, the original referenced object is modified.

References are especially useful in function parameters, object-oriented programming, standard library code, and applications that work with large objects. They can help avoid unnecessary copies while providing clean and convenient syntax.

Understanding references also prepares you for pointers. References provide aliasing semantics, while pointers explicitly store memory addresses and provide additional capabilities such as null states and reseating.

Next Lesson →

Pointers