C++右值引用

2021/5/8 1:25:24

本文主要是介绍C++右值引用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

C++右值引用

#概念

关于右值引用,《C++ Primer》中已经简单的介绍了一下概念,这里直接上图。

#具体实现和思考

这里我改了一个同学的代码来举一个简单的例子:

 1 #include <iostream>
 2 using namespace std;
 3 class A {
 4     public:
 5         A() = default;
 6         A(int x, int y) : a(x), b(y) { }
 7         //A(const A &temp) {cout << "flag1" << endl;}
 8         A(A &&temp) {cout << "flag2" << endl;}
 9         A operator+(A &temp) {
10             return A(this->a + temp.a, this->b + temp.b);
11         }
12         void Display() {cout << this->a << ' ' << this->b << endl;}
13     private:
14         int a = 0, b = 0;
15 };
16 int main() {
17     A a(1, 1);
18     A b(2, 2);
19     A c = a + b;
20     c.Display();
21     return 0;
22 }

可以看到,第9行是一个重载+号的函数,这个函数在return的时候会调用第6行的默认构造函数,然后返回这个构造的对象,然后主函数第19行中的A c = a + b来进行接收,在接收的同时该语句又会自动调用一次第8行的拷贝构造函数(移动拷贝构造函数),最终完成重载。

 A(A &&temp) {cout << "flag2" << endl;} 

需要注意的是第8行拷贝构造函数的形参其实是一个右值引用,带有两个&&。这是因为这个时候的a + b其实是一个右值,一个马上就会被销毁的变量,所以形参不可以是普通引用。

比如:

1 1 int &a = 5;  //错误
2 2 int &&b = 5;  //正确
3 3 const int &c = 5;  //正确

第一行是错误的,因为5是一个常量,是一个右值,不可以用普通的引用。

第二行是正确的,右值引用刚好符合。

第三行是正确的,因为我们可以将一个const的引用绑定到一个右值上。

同样的道理,对于上面的程序,同样可以调用上面第7行的拷贝构造函数来实现:

   A(const A &temp) {cout << "flag1" << endl;} 

其实现效果和上述移动拷贝构造函数相似。

#扩展

同样的,当我们在使用一个需要传入右值的函数时,右值引用可以使程序减少一些开销,比如下面两个程序:

程序1:

 1 #include <iostream>
 2 using namespace std;
 3 void f(int &x) {
 4 
 5 }
 6 int main() {
 7     int x = 10;
 8     int y = x * 5;
 9     f(y);
10     return 0;
11 }

程序2:

 1 #include <iostream>
 2 using namespace std;
 3 void f(int &&x) {
 4 
 5 }
 6 int main() {
 7     int x = 10;
 8     f(x * 5);
 9     return 0;
10 }

可以看到,程序2比程序1少申请了一个临时变量。

c++11中新增的emplace函数(vector的成员函数)就是基于右值引用实现的,比push节省空间开销。

 


仅作自己强化记忆的笔记

 



这篇关于C++右值引用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程