A reference is another name, or alias, for an existing variable. Once a reference is initialized, it refers to the same object for its lifetime. References are commonly used to pass variables to functions without making a copy and to allow functions to modify the original data.
A reference is an alias for an existing variable.
int number = 10;
int& ref = number;
Here, ref is another name for number.
The basic syntax for creating a reference is:
dataType& referenceName = variableName;
Example:
int age = 20;
int& studentAge = age;
Both age and studentAge refer to the same
integer object.
#include <iostream>
int main() {
int number = 50;
int& ref = number;
std::cout << number << std::endl;
std::cout << ref;
return 0;
}
Output:
50
50
Changing a reference changes the original variable because both refer to the same object.
int number = 10;
int& ref = number;
ref = 100;
std::cout << number;
Output:
100
A reference must be initialized when it is declared.
int number = 10;
int& ref = number;
This is valid because ref is immediately connected to
number.
A reference cannot simply be declared without an initializer.
int number = 25;
int& ref = number;
std::cout << "Number = "
<< number
<< std::endl;
std::cout << "Reference = "
<< ref;
The reference provides another way to access the same object.
A reference does not represent a separate object in the way another ordinary variable would. Taking its address gives the address of the object it refers to.
int number = 10;
int& ref = number;
std::cout << &number << std::endl;
std::cout << &ref;
Both expressions refer to the same object's address.
int number = 10;
double price = 25.5;
char grade = 'A';
int& numberRef = number;
double& priceRef = price;
char& gradeRef = grade;
The reference type should be compatible with the object it refers to.
A reference parameter allows a function to work directly with the original variable.
void change(int& number) {
number = 100;
}
int main() {
int value = 10;
change(value);
std::cout << value;
return 0;
}
Output:
100
When a function parameter is declared as a reference, the function can modify the caller's object.
void increase(int& number) {
number++;
}
int main() {
int value = 10;
increase(value);
std::cout << value;
return 0;
}
Output:
11
| Pass by Value | Pass by Reference |
|---|---|
| Receives a separate value. | Refers to the original object. |
| Changes normally do not affect the caller's variable. | Changes can affect the caller's variable. |
| Useful when a separate copy is desired. | Useful when modifying or avoiding a copy is desired. |
void swapValues(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 10;
int y = 20;
swapValues(x, y);
std::cout << x << " "
<< y;
return 0;
}
Output:
20 10
A const reference can refer to an object without allowing
modification through that reference.
int number = 50;
const int& ref = number;
std::cout << ref;
The following would not be allowed through ref:
// ref = 100;
Const references are useful when a function needs to read an object without modifying it.
void display(const std::string& name) {
std::cout << name;
}
This allows the function to read the string without making a copy and prevents the function from modifying it through the parameter.
#include <iostream>
#include <string>
void display(const std::string& text) {
std::cout << text;
}
int main() {
std::string message =
"Hello C++";
display(message);
return 0;
}
A const reference is commonly used for passing strings efficiently when the function only needs to read them.
A reference can refer to an entire array, preserving its size in the type.
int numbers[5] = {
10, 20, 30, 40, 50
};
int (&ref)[5] = numbers;
std::cout << ref[0];
Output:
10
void display(int (&numbers)[5]) {
for (int i = 0; i < 5; i++) {
std::cout << numbers[i]
<< " ";
}
}
int main() {
int numbers[5] = {
10, 20, 30, 40, 50
};
display(numbers);
return 0;
}
The reference parameter preserves the array's size.
A function can return a reference, but the referenced object must continue to exist after the function returns.
int& getValue(int& number) {
return number;
}
int main() {
int value = 10;
getValue(value) = 50;
std::cout << value;
return 0;
}
Output:
50
A function should not return a reference to a local variable because the local variable is destroyed when the function ends.
// Incorrect
int& getNumber() {
int number = 10;
return number;
}
After a reference is initialized, it cannot later be made to refer to a different object.
int a = 10;
int b = 20;
int& ref = a;
ref = b;
The last statement assigns the value of b to
a. It does not make ref refer to
b.
| Reference | Pointer |
|---|---|
| Alias for an existing object. | Stores an address. |
| Must be initialized. | Can be initialized with nullptr. |
| Cannot normally be reseated. | Can point to different objects. |
| Used directly like the referred object. | Usually requires dereferencing to access the pointed-to object. |
| Useful for reference-based function parameters. | Useful when nullable or address-based behavior is needed. |
A const reference can refer to a const object.
const int number = 100;
const int& ref = number;
std::cout << ref;
The value cannot be modified through ref.
void calculate(int& result) {
result = 10 + 20;
}
int main() {
int answer = 0;
calculate(answer);
std::cout << answer;
return 0;
}
Output:
30
The function directly updates the caller's variable.
void calculate(
int a,
int b,
int& sum,
int& product
) {
sum = a + b;
product = a * b;
}
int main() {
int sum;
int product;
calculate(5, 4, sum, product);
std::cout << "Sum = "
<< sum << std::endl;
std::cout << "Product = "
<< product;
return 0;
}
References can be useful in range-based for loops when
you want to modify the elements of a container.
int numbers[5] = {
1, 2, 3, 4, 5
};
for (int& number : numbers) {
number *= 2;
}
Each number refers directly to an array element.
#include <iostream>
void swapValues(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int first = 10;
int second = 20;
std::cout << "Before swap: "
<< first << " "
<< second
<< std::endl;
swapValues(first, second);
std::cout << "After swap: "
<< first << " "
<< second;
return 0;
}
Output:
Before swap: 10 20
After swap: 20 10
#include <iostream>
void updateMarks(int& marks) {
if (marks < 40) {
marks = 40;
}
}
int main() {
int marks = 35;
updateMarks(marks);
std::cout << "Marks = "
<< marks;
return 0;
}
The function changes the original marks variable because it
receives it by reference.
| Concept | Meaning |
|---|---|
| Reference | An alias for an existing object. |
| & | Used in a reference declaration or reference parameter. |
| Initialization | A reference must be initialized when declared. |
| Pass by Reference | Allows a function to work with the caller's object. |
| const Reference | Allows reading without modifying through that reference. |
| Reference Return | A function can return a reference when the referred object remains alive. |
| Pointer vs Reference | Pointers store addresses; references act as aliases. |
void change(int& value) {
value = 100;
}
int main() {
int number = 10;
change(number);
std::cout << number;
return 0;
}
Question: What is a reference in C++?