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
xxxxxxxxxx
71vector<string> names{"Jack", "Sunny", "Yena"};
2
3for (auto name : names)
4 name = "Hello"; // Changes the copy
5
6for (auto name: names)
7 cout << name << endl; // Jack Sunny Yena
xxxxxxxxxx
71vector<string> names{"Jack", "Sunny", "Yena"};
2
3for (auto &name : names)
4 name = "Hello"; // Changes the actual
5
6for (auto name: names)
7 cout << name << endl; // Hello Hello Hello
xxxxxxxxxx
41vector<string> names{"Jack", "Sunny", "Yena"};
2
3for (auto const &name : names)
4 name = "Hello"; // Compiler error
xxxxxxxxxx
41vector<string> names{"Jack", "Sunny", "Yena"};
2
3for (auto const &name : names)
4 cout << name << endl; // Jack Sunny Yena
Passing reference to functions
Values that have names and are addressable
Modifiable if they are not constants
Example
xxxxxxxxxx
61int x{100}; // x is an l-value
2x = 1000;
3x = 1000 + 20;
4
5string name; // name is an l-value
6name = "Jack";
xxxxxxxxxx
61100 = x; // Error: 100 is NOT an l-value
2(1000 + 20) = x; // Error: (1000 + 20) is NOT an l-value
3
4string name;
5name = "Jack";
6"Jack" = name; // Error: "Jack" is NOT an l-value
A 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
xxxxxxxxxx
71int x{100}; // 100 is an r-value
2int y = x + 200; // (x + 200) is an r-value
3
4string name;
5name = "Jack"; // "Jack" is an r-value
6
7int max_num = max(20, 30); // max(20, 30) is an r-value
R-values can be assigned to L-values
xxxxxxxxxx
51int x{100};
2int y{0};
3
4y = 100; // R-value 100 assigned to l-value y
5x = x + y; // R-value (x + y) assgiend to l-value x
The references we've used are l-value references because we are referencing l-values.
xxxxxxxxxx
61int x{100};
2
3int &ref1 = x; // ref1 is reference to l-value
4ref1 = 1000;
5
6int &ref2 = 100; // Error: 100 is an r-value
The same when we pass-by-reference
xxxxxxxxxx
81int square(int &n)
2{
3 return n * n;
4}
5
6int num{10};
7square(num); // OK
8square(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