Table of Contents
References
In C++, a reference is an alias for an existing object. Once a reference is defined, any operation performed on the reference is applied to the referenced object.
Even if it seems ridiculous at first. In fact, references are one of the most important features of C++.
In C++, references to functions can also be created. However, this usage is not very common.
There are two types of references in C++. These are r-value and l-value references.
L-Value References
An lvalue reference acts as an alias for an existing lvalue.
To declare an lvalue reference, & is appended to the type of the reference.
int // a normal int type int& // An lvalue reference to an object of type int double& // An lvalue reference to an object of type double
L-Value Reference Variable
One of the things you can do with an lvalue reference type is to create an lvalue reference variable. An lvalue reference variable is a variable that acts as a reference to an lvalue.1)
int x { 5 }; // x is a normal int variable int& ref { x }; // ref is now an lvalue reference variable that can be used as an alias for variable x std::cout << x << '\n'; // prints the value of x, i.e. 5 std::cout << ref << '\n'; // prints the value of x, i.e. 5, via ref
When defining a reference, place the & sign next to the type.2)
References are not objects in C++. A reference does not need to exist or occupy memory space. If possible, the compiler will optimize references by replacing them with the referenced object wherever a reference is used. However, this is not always possible and in such cases references may require memory space.
For this reason, the naming of the reference variable is a bit misleading. Because references are not objects.
Since references are not objects, they cannot be used wherever an object is required. In cases where you need a reference that is an object or a reference that can be reassigned, you can use std::reference_wrapper
.
Like constants, references must be initialized when declared.
int& invalidRef; // ERROR: references must be initialized int x { 5 }; int& ref { x }; // The int reference is bound to the int variable. }
When references are initialized, they are bound to the object they refer to. This is called reference binding. Once bound, they cannot refer to another object. That is, a bound reference cannot be reassigned to refer to another object.
Lvalue references can only be bound to mutable lvalue objects. They cannot be bound to const
objects. Because then those objects can be interfered with through the reference.
References and the lifetimes of the objects they refer to are independent of each other.
- References can be deleted before the object they are linked to.
- Referenced objects can be deleted before their references.
This latter situation can cause leakage. If the object referred to by a reference is deleted and an attempt is made to access that object via the reference, undefined behavior occurs.
Const L-Değeri Referansları
If the const
keyword is used when defining Lvalue references, these references behave as if the object they depend on is a constant.
The object to which the reference is bound is not necessarily fixed. Even if the background object can be changed, it cannot be changed via the const lvalue reference.
const int x { 5 }; // x is an lvalue that cannot be changed. const int& ref_x { x }; // ref_x is an lvalue reference to a const value int y { 5 }; // x is a mutable lvalue. const int& ref_y { x }; // we can bind a const reference to a mutable lvalue ref_y = 7; // ERROR: We cannot modify an object via const reference
In cases where you don't need to change the referenced object, it is better to use const
lvalue references.
Const lvalue references can also be bound to rvalue.
const int& ref { 5 }; // 5 is an rvalue. std::cout << ref << '\n'; // Prints 5.
In such a case a temporary object is created and initialized with rvalue. Our reference is bound to this temporary object.
Normally, as we know, temporary objects are deleted at the end of the current expression. But in this case our reference must cause a leak. To avoid this, C++ extends the lifetime of the temporary object for this specific case.
When a const lvalue reference is bound to a temporary object, the lifetime of the temporary object is extended to match the lifetime of the reference.
Taken from UCH Viki https://wiki.ulascemh.com/doku.php?id=en:cs:cpp:common:reference