Home | Projects | Notes > C++ Programming > References
What is a reference?
Review passing references to functions
const and references
Reference variables in range-based for loops
Potential reference pitfalls
Raw vs. Smart pointers
An alias for a variable
Must be initialized to a variable when declared
Cannot be null
Once initialized cannot be made to refer to a different variable
Very useful as function parameters
Might be helpful to think of a reference as a constant pointer that is automatically dereferenced
Using references in a range-based for loop
xxxxxxxxxx71vector<string> names{"Jack", "Sunny", "Yena"};2
3for (auto name : names)4 name = "Hello"; // Changes the copy5
6for (auto name: names)7 cout << name << endl; // Jack Sunny Yenaxxxxxxxxxx71vector<string> names{"Jack", "Sunny", "Yena"};2
3for (auto &name : names)4 name = "Hello"; // Changes the actual5
6for (auto name: names)7 cout << name << endl; // Hello Hello Helloxxxxxxxxxx41vector<string> names{"Jack", "Sunny", "Yena"};2
3for (auto const &name : names)4 name = "Hello"; // Compiler errorxxxxxxxxxx41vector<string> names{"Jack", "Sunny", "Yena"};2
3for (auto const &name : names)4 cout << name << endl; // Jack Sunny YenaPassing reference to functions
Values that have names and are addressable
Modifiable if they are not constants
Example
xxxxxxxxxx61int x{100}; // x is an l-value2x = 1000;3x = 1000 + 20;4
5string name; // name is an l-value6name = "Jack";xxxxxxxxxx61100 = x; // Error: 100 is NOT an l-value2(1000 + 20) = x; // Error: (1000 + 20) is NOT an l-value3
4string name;5name = "Jack";6"Jack" = name; // Error: "Jack" is NOT an l-valueA value that's not an l-value
On the right-hand side of an assignment expression
A literal
A temporary which is intended to be non-modifiable
Non-addressable and non-assignable
Example
xxxxxxxxxx71int x{100}; // 100 is an r-value2int y = x + 200; // (x + 200) is an r-value3
4string name;5name = "Jack"; // "Jack" is an r-value6
7int max_num = max(20, 30); // max(20, 30) is an r-valueR-values can be assigned to L-values
xxxxxxxxxx51int x{100};2int y{0};3
4y = 100; // R-value 100 assigned to l-value y5x = x + y; // R-value (x + y) assgiend to l-value xThe references we've used are l-value references because we are referencing l-values.
xxxxxxxxxx61int x{100};2
3int &ref1 = x; // ref1 is reference to l-value4ref1 = 1000;5
6int &ref2 = 100; // Error: 100 is an r-valueThe same when we pass-by-reference
xxxxxxxxxx81int square(int &n)2{3 return n * n;4}5
6int num{10};7square(num); // OK8square(5); // Error: can't reference r-value 5
Pass-by-value
When the function does NOT modify the actual parameter
When the parameter is small and efficient to copy like simple types (int, char, double, etc.)
Pass-by-reference using a pointer
When the function does modify the actual parameter
When the parameter is expensive to copy
It's OK for the pointer to contain a nullptr value
Pass-by-reference using a pointer to const
When the function does NOT modify the actual parameter
When the parameter is expensive to copy
It's OK for the pointer to contain a nullptr value
Pass-by-reference using a const pointer to const
When the function does NOT modify the actual parameter
When the parameter is expensive to copy
It's OK for the pointer to contain a nullptr value
When you don't want to modify the pointer itself
Pass-by-reference using a reference
When the function DOES modify the actual parameter
When the parameter is expensive to copy
The parameter will never be nullptr
Pass-by-reference using a const reference
When the function does NOT modify the actual parameter
When the parameter is expensive to copy
The parameter will never be nullptr