C++11 new feature ----- rvalue reference

Let me talk about citations

References in C++ can be understood as giving a variable an alias, just like we all have our own names, and there are also many people who have their own nicknames, nicknames, etc., just like Zhang San’s nickname - Ergou is Zhang One of the quotes from San, encountering San either said Hey! Zhang San! Still hey! Two dogs! Zhang San can know that someone is calling his name, so here is the quote

Quoted Features

Before talking about the characteristics of lvalue references and rvalue references, we must always keep in mind a problem. Both rvalue references and lvalue references are essentially reference types, and they all have the characteristics and functions of references. Let’s talk about them first. The characteristics and functions of the following references.

Features:

  1. A reference must be initialized when it is declared, and its pointing cannot be changed once initialized.
  2. The reference itself does not occupy memory space, it just creates an alias for an existing variable, so there is no need for additional memory allocation and copying when used.
  3. References can be used as parameters and return values ​​of functions, which can avoid the overhead of copying large objects (this is also one of the great functions of rvalue references) , and improve the efficiency of programs.
  4. References simplify code and make it clearer and easier to understand.

effect:

  1. As a function parameter: the reference can be passed as a function parameter, which can avoid copying the parameter by the function and improve the efficiency of the program.
  2. As a function return value: the reference can be used as the return value of the function, which can avoid the function
  3. Return a copy of the large object to improve the efficiency of the program.

  4. Simplify code: References simplify code, making it clearer and more readable.

  5. Implement overloading of functions or operators: References can be used to implement overloading of functions or operators, making the code more flexible and extensible.

  6. Reference as an alias of an object: A reference can be used as an alias of an object, can be used to modify the value of an object, or be used to manipulate members of an object.

rvalue reference

C++11 introduces the concept of rvalue reference, which is a new type of reference used to refer to temporary objects. Before we understand rvalue references, we finally need to understand the concept of rvalues.

rvalue:

Rvalues ​​can be roughly understood as values ​​that (can only be) placed on the right side of the equal sign, that is, temporary objects or literal constants that cannot be addressed. Rvalues ​​can be basic data types or objects, including temporary objects and function return values.

Rvalues ​​have the following characteristics:

  1. Rvalues ​​are temporary: rvalues ​​are created temporarily within an expression and are destroyed once the expression ends.

  2. Rvalue does not have an address: an rvalue has no specific memory address, so it cannot be addressed.

  3. Rvalues ​​can be moved in expressions: Since rvalues ​​are temporary, they can be moved in expressions without copying.

The role of rvalue references

If we want to understand rvalue references, we must first understand the reason for its appearance, and the appearance of rvalue references is precisely to use rvalues ​​that are difficult to be used normally, avoid frequent creation and destruction of space, and greatly improve the efficiency of the program. We can see the result of running the code below.

#include<iostream>
using namespace std;

class A
{
public:
	int a;
	A() {};
	A(int num):a(num) {};
	A test(A a)
	{
		a.a = 1;
		return a;
	}
	A test2(A&& a)
	{
		cout << "test2";
		return a;
	}
	~A()
	{
		cout << "销毁了一个A对象"<<endl;
	}


};
void main()
{
	A a;
	a.test(a);
	char c = getchar();
}

We can see that when the program runs to getchar blocking, the destructor is called twice, and the two times here are the object creation and destruction that occur when the function passes parameters and the function returns.

At this point we modify the program to this:

#include<iostream>
using namespace std;

class A
{
public:
	int a;
	A() {};
	A(int num):a(num) {};
	A test(A a)
	{
		a.a = 1;
		return a;
	}
	A test2(A&& a)
	{
		cout << "test2";
		return a;
	}
	~A()
	{
		cout << "销毁了一个A对象"<<endl;
	}


};
void main()
{
	A a;
	A && b = a.test(move(a));//move函数将a这个左值转化为右值
	char c = getchar();
}

 Run again at this time, we will find that the function will not call the destructor before getchar() blocks, that is to say, no new objects are created and destroyed.

In this way, we save two object creation and destruction. If the class A becomes very large, then the rvalue reference will save us a lot of program overhead. This is the great advantage of rvalue references.

The characteristics and functions of rvalue references:

Features:

  1. Rvalue references are declared using the && symbol, for example int&& x = 10;.

  2. Rvalue references can only bind to rvalues, not lvalues.

  3. Rvalue references can be assigned and copied, but the state of the copied object will be transferred, that is, the copied object becomes an empty object.

  4. Rvalue references can be used to implement move semantics (move), that is, to transfer the resource ownership of an object from one object to another, avoiding unnecessary copy and destruction operations.

  5. Rvalue references can be used to achieve perfect forwarding (forward), that is, to forward the parameters of one function to another function, so that the type and value of the forwarded parameters can remain unchanged.

  6. Rvalue references can be used to optimize code. For example, when returning temporary objects, rvalue references can be used to avoid unnecessary copy operations and improve program efficiency.

effect:

  1. Realize move semantics: Move semantics can be realized through rvalue references, avoiding unnecessary copy and destruction operations, and improving program efficiency.

  2. Realize perfect forwarding: perfect forwarding can be realized through rvalue reference, which avoids the change of parameter type and value, and improves the flexibility and scalability of the program.

  3. Optimized code: unnecessary copy operations can be avoided through rvalue references, and the efficiency of the program can be improved.

  4. Implement overloading of functions or operators: rvalue references can be used to implement overloading of functions or operators, making the code more flexible and extensible.

 move:

C++11 adds rvalue references, but cannot initialize rvalue references with lvalues. In some specific cases, it is inevitable to need lvalues ​​to initialize rvalue references (calling move construction with lvalues). If you want to initialize one with lvalues Rvalue references require the help of the std::move() function. The move() function can convert an lvalue to an rvalue. Like I demonstrated above.

forward:

The rvalue reference type is independent of the value. When an rvalue reference is used as a formal parameter of a function parameter, when the parameter is forwarded inside the function to other internal functions, it becomes an lvalue (when the rvalue is named, it is compiled The implementer will think he is an lvalue), not the original type. If forwarding to another function according to the original type of the parameter, you can use the std::forward() function of c++11. The function implemented by this function is called perfect forwarding.

#include <iostream>
using namespace std;

template<typename T>
void printValue(T& t)
{
	cout << "左值引用: " << t << endl;
}

template<typename T>
void printValue(T&& t)
{
	cout << "右值引用:" << t << endl;
}

template<typename T>
void testForward(T&& v)
{
	printValue(forward<T>(v));
	cout << endl;
}

int main()
{
	testForward(520);//右值类型,转化为右值引用
	int num = 1314;
	testForward(num);//左值引用,转化为左值
	testForward(forward<int>(num));//forward将num转化为右值,再转发为右值
	testForward(forward<int&>(num));//forward将num转化为左值引用,再转发为左值
	testForward(forward<int&&>(num)); // forward将num转化为右值,再转发为右值
	return 0;
}

You can see the running results:

 At this time, the testForward function is called a perfect forwarding function.

Guess you like

Origin blog.csdn.net/asdasd121312dasd/article/details/131879762