References
Declaring a named variable as a reference, i.e., an alias for an existing object or function.
References can be thought of as C++'s encapsulated non-null pointers, used to refer to the objects they point to, and must be bound to an object upon declaration.
References are not objects; therefore, there are no arrays of references, pointers to references cannot be obtained, and there are no references to references.
Reference types are not object types
If you want references to support general operations like copying and assignment, such as being used as container elements, you need reference_wrapper, which typically maintains a non-null pointer.
References are mainly divided into two types: lvalue references and rvalue references.
Lvalues and rvalues
For an explanation of lvalues and rvalues, refer to the Value Category page.
Lvalue Reference T&
The references we commonly encounter are lvalue references, i.e., references bound to lvalues. Additionally, const-qualified lvalue references can bind to rvalues. The following is an example code snippet from the reference manual.
1 2 3 4 5 6 7 8 9 10 11 12 | |
Lvalue references are most commonly used as function parameters to avoid unnecessary copying.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Rvalue Reference T&& (C++11)
Rvalue references are references bound to rvalues, used for moving objects and can also be used to extend the lifetime of temporary objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Dangling References
When the object a reference refers to is destroyed, the reference becomes a dangling reference. Accessing a dangling reference is undefined behavior and may cause program crashes.
Common examples of dangling references include:
-
Reference to a local variable
1 2 3 4 5 6 7 8 9 10 11
#include <iostream> int& foo() { int a = 1; return a; } int main() { int& b = foo(); std::cout << b << std::endl; // Undefined behavior } -
Dangling reference due to deallocation
1 2 3 4 5 6 7 8 9
#include <iostream> int main() { int* ptr = new int(10); int& ref = *ptr; delete ptr; std::cout << ref << std::endl; // Undefined behavior } -
Dangling reference due to memory reallocation
1 2 3 4 5 6 7 8 9 10 11
#include <iostream> int main() { std::string str = "hello"; const char& ref = str.front(); str.append("world"); // May reallocate memory, causing the memory pointed to by ref to be freed std::cout << ref << std::endl; // Undefined behavior }Similar to
std::vector, insertion operations in containers likestd::unordered_mapmay also cause memory reallocation.
When using references, always be mindful of the lifetime of the object the reference points to to avoid creating dangling references.
Static analysis tools and good coding practices can help us avoid dangling reference issues.
Optimization Techniques Related to References
Eliminating Copy Overhead for Non-Trivial Object Parameters
Common non-trivial objects include:
- Containers like
vector,array,map, etc. string- Other types that implement or inherit custom copy constructors, move constructors, or other special functions
Using references for trivial objects offers no benefit; the size of a reference type as a parameter may even be larger than the type itself.
This can introduce performance overhead and may prevent compiler optimizations.
The following are considered trivial objects:
- Fundamental types like
int,float, etc. - Small aggregate types
- Standard library container iterators
Converting Lvalues to Rvalues
Use std::move to transfer ownership of an object. This is commonly seen between local variables or between parameters and local variables:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
However, this is not always necessary, such as in return value optimization.
Extending Temporary Lifetime with Rvalue References
Semantically, temporaries may cause additional copies or moves. Although compilers can often optimize these away via copy elision, references can force the compiler to avoid these redundant operations, eliminating uncertainty.
References
- C++ Language Documentation—Reference Declaration
- C++ Language Documentation—Value Category
- Does const ref lvalue to non-const func return value specifically reduce copies?
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用