After c++11, the C + + reference is expanded to a very good lvalue reference, a constant lvalue reference, a very important rvalue reference, and a constant rvalue reference.
What are lvalue values? What are rvalue values? Both Lvalue and rvalue are for expressions, and Lvalue refers to persistent objects that persist after an expression ends, and an rvalue is a temporary object that does not exist at the end of an expression. A convenient way to differentiate between Lvalue and rvalue is to see if you can take an address on an expression, or, if so, an lvalue, or an rvalue.
What is a reference? The reference is not an object, but instead it is just another name for an already existing object. Once a reference is defined, all operations on it are performed on the object to which it is bound.
References are also classified as constant references, non-const references, and they are distinguished by the ability to do all the work with the object being bound by a non-const reference, and the object to which it is bound cannot be modified by a constant reference.
A reference needs to be initialized at the same time as the definition, which is to complete binding to an object. The above four types of references are required for objects that can be bound to them.
A very good lvalue reference (T & = x): x can only be a very good left-hand value of type T.
Constant Lvalue Reference (const T & = x): X can be an lvalue, or it can be a right value. The type of x can be of type T and all other types that can be implicitly converted to type T. X can be both constant and very mass.
A very good rvalue reference (T && = x): If x is of type T, then it must be a very right value. If x is another type that can be implicitly converted to type T, both the left and right values are available.
Constant Rvalue Reference (const T && = x): constant, very right value that can point to type T. If x is another type that can be implicitly converted to type T, both the left and right values are available.
When the object that references the binding is destroyed, the reference is invalidated, and using the invalid reference is undefined behavior, which is usually a program crash. Therefore, it is necessary to focus on when the object that references the binding is destroyed. Referencing the bound lvalue is fine, but pointing to the right value doesn't mean that the right value is destroyed after the expression ends? What's the use of the reference to that definition? Throw undefined behavior? There are two scenarios for reference definitions: function parameter passing, other.
First, the function parameter is passed. For example, the function is declared void Fun (const string & param), and is invoked with an rvalue initialization param:fun (string ()); As you can see, string () is an rvalue, fun (String ()) is destroyed after the expression is finished, but the fun function has run out, so the reference param has been in effect during the fun run. Therefore, this scenario refers to the binding right value at all without problems.
In other cases (function scope, global scope, definition reference within class scope), take function scope as an example:
classtest1{ Public: Test1 (int) {cout<<"cc"<<Endl; } test1 (ConstTest1 &) {cout<<"Copy"<<Endl; } ~test1 () {cout<<"Destroy"<<Endl;}};voidFun () {ConstTest1 &x = test1 (2);
Test1 y (x);}
In the above code, X is bound to an rvalue, and the right value follows the norm, in the const test1 &x = test1 (2); This expression is destroyed when it is finished, but not in fact. In this case, the lifetime of the right value is extended, and test1 (2) is equivalent to an anonymous lvalue variable that is destroyed when it exits its scope. Its behavior is equivalent to the following code:
void Fun () { test1 tmp (2); Const Test1 &x = tmp; Test1 y (x);}
The right value discussed above does not include literal constants, and if the rvalue is a literal constant, the compiler defines a temporary variable for it to store its value, and then the reference binds to that temporary variable. Of course, this temporary variable is also a right value, so its life-time law is the normal right-value law.
Constant Lvalue references const T & = x, x can also point to an lvalue, an rvalue that is not of type T, as long as the type of x can be implicitly converted to type T. The principle is this: the compiler implicitly converts x to a temporary variable of type T, and then the constant lvalue reference binds to the temporary variable. This temporary variable is of course a right value. The law of the life of the right value has been said above.
classtest1{ Public: Test1 (int) {cout<<"cc"<<Endl; } test1 (ConstTest1 &) {cout<<"Copy"<<Endl; } ~test1 () {cout<<"Destroy"<<Endl;}};intMain () {test1 x (3); //test1 && y = x; //error, rvalue reference can only point to right value inti =3; Test1&& y = i;//right,y points to a temporary variable that is generated with I: Right valueSystem"Pause"); return 0;}
C + + Reference