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.
int number = 100;Normally, creating another variable and assigning number to it creates a separate variable containing a copy of the value.
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.
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.
int number = 100;
int &ref = number;In this example, number is the original variable and ref is a reference bound to number.
number ─────┐
├────► Same int object
ref ─────────┘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.
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.
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.
data_type &reference_name = variable_name;int number = 100;
int &ref = number;| Part | Meaning |
|---|---|
| int | The type of object being referenced |
| & | Indicates an lvalue reference in this declaration |
| ref | The reference name |
| number | The existing variable to which the reference is bound |
After the declaration, ref can be used to access the same int object as number.
std::cout << number;
std::cout << ref;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.
int number = 100;
int &ref = number;Names
────────────────────
number ──────┐
│
ref ─────────┘
│
▼
┌─────────┐
│ 100 │
└─────────┘
int objectBoth names provide access to the same int object. Therefore, changing the value through either name changes the value observed through the other.
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.
Conceptually, number and ref are two names used to access the same object.
Example 1: Creating a Reference
#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.
100
100Both names display the same value because they access the same object.
Example 2: Modifying Through a Reference
#include <iostream>
int main()
{
int number = 50;
int &ref = number;
ref = 80;
std::cout << number << std::endl;
std::cout << ref;
return 0;
}number ─────┐
├────► 50
ref ─────────┘number ─────┐
├────► 80
ref ─────────┘80
80Assigning 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.
// ❌ Incorrect
int &ref;
// ✅ Correct
int value = 10;
int &ref = value;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.
Before:
a = 10
b = 20
ref refers to a
After ref = b:
a = 20
b = 20
ref still refers to aOnce 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
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
| Feature | Variable | Reference |
|---|---|---|
| Purpose | Represents its own object | Acts as an alias for an existing object |
| Initialization | May sometimes be declared without an initializer | Must be initialized |
| Independence | Exists as its own object | Depends on an object to reference |
| Assignment | Changes its stored value | Changes the referenced object |
| Reseating | Not applicable | Cannot be reseated after initialization |
References vs Pointers
| Feature | Reference | Pointer |
|---|---|---|
| Concept | Alias for an object | Object that stores an address |
| Initialization | Must be initialized | Can be default-initialized or explicitly initialized depending on context |
| Null State | A valid reference is expected to refer to an object | Can hold nullptr |
| Reseating | Cannot be reseated | Can be changed to point elsewhere |
| Access Syntax | Normal variable syntax | Usually requires dereferencing with * |
| Address Storage | Reference semantics | Explicitly stores a memory address value |
int value = 10;
int &ref = value;
ref = 20;int value = 10;
int *ptr = &value;
*ptr = 20;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.
void updateScore(int &score)
{
score = score + 10;
}int score = 50;
updateScore(score);
std::cout << score;60References 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
A reference must be initialized when it is declared.
A reference is an alias. Changes through it affect the referenced object.
References provide aliasing semantics, while pointers explicitly store addresses.
Assignment through a reference modifies the referenced object instead of reseating the reference.
A reference must never be used after the object it refers to has been destroyed.
// ❌ Incorrect
int &ref;
// ✅ Correct
int value = 10;
int &ref = value;int number = 10;
int &ref = number;
ref = 50;
std::cout << number;50int a = 10;
int b = 20;
int &ref = a;
ref = b;
// a is now 20.
// ref still refers to a.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.
void increase(int &value)
{
value++;
}void displayName(const std::string &name)
{
std::cout << name;
}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.