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++右值引用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享