前言:
c++ 右值引用确实比较难理解,一遍看不懂,就多看两遍多看几篇,直到掌握为止,一定要掌握
右值引用 这个知识点对提升自己还是比较重要的我认为
1.什么是左值 什么是右值?
c++ 98 中 每个值 不是左值就是右值 2选1
c++ 11 中 分为 左值 ,右值 {存右值,将亡值} 3个 暂且先认为还是2个
ok
有人可能认为等号左边就是左值 等号右边的就是右值 错误太绝对了
通俗讲 能取地址的就是左值
auto i = 0; // i是左值 0是右值
int getValue()
{
auto i = 5;
return i;
}
auto i = getValue(); //i是左值 getValue()是右值(临时变量)
2.左值引用
int i = 0;
int &a = i;// i是左值,a是左值引用i
a = 10; // 这时i也为10
int&
int &i = 10; // 错误 10为右值不能被绑定
const int&i = 10; //正确 这个是特殊的 只要加了const 常量引用既可以绑定左值又可以绑定右值
左值引用只能绑定左值
常量引用既可以绑定左值又可以绑定右值
3.右值引用
右值引用的作用 : 减少不必要的拷贝,提高程序的运行效率
c++ 11 中 右值引用的符号为 &&
int &&a = 10; //正确,现在相当于给10续命了 只要a不死掉,10就死不掉
int i = 10;
int &&a = i; //错误.右值引用只能绑定右值
看到这里是不是还没发现右值引用的好处,也不是很理解到底是干啥的
继续向下看↓
看一下这个类的结构
带参构造
拷贝构造
析构
如果不明白拷贝构造 为啥要申请地址请看这一篇 深浅拷贝
https://blog.youkuaiyun.com/weixin_42837024/article/details/99673841
我向容器中塞入100个persion 每次都要申请释放地址,而且还是一个临时的变量,我后面不再使用它,这没有意义
如果我能够直接的用临时对象已经申请的资源,既能节省资源又能避免不必要的浪费时间
c++ 11 移动语义 就可以解决
4.移动语义
来写一个移动构造
看见没 进的移动构造 而不进拷贝构造了 为啥
拷贝构造的参数是 const Persion& p 常量引用
移动构造的参数是 Persion &&p 右值引用
而Persion(“ShenMingYi”)是临时对象,是右值,所以优先进入移动构造,而不是拷贝构造
移动构造与拷贝构造相比还有一个好处:
他没有申请一块新的内存,把对象的内容复制过来
而是直接把指针指向别人的资源,把自己的指针设为nullptr
右值可以优先进移动拷贝,那我是左值会怎样
完蛋了 左值没法进入移动构造了
别慌!
c++11 提供了一种 把左值 转换为右值的
5.std::move()
是不是就进入移动构造了
执行完 move 的s 就是空了 ,相当于直接把自己给了s2,而不是复制一份
其实这时候 s 还没有死 还没有析构,当他出了作用域才会被析构
但是最好别再使用它了,可能会发生意向不到的结果