这篇为了理解,自己瞎写的,建议看下面这篇,里面例子很好很有用
https://blog.csdn.net/u011726005/article/details/79874539 //这篇很好
左值右值参考:
https://www.cnblogs.com/jiangbin/p/7066950.html?utm_source=itdadao&utm_medium=referral
左值就是=号左边的值,可以被赋值,可以取地址。
右值就是=号右边的的值,不能被赋值
v.push_back(A(25));
A(25) 实参是右值,临时的。 类对象的非引用方式的返回值也是右值,拷贝完就扔。移动语义就是在碰到传递右值的时候触发移动构造函数或者移动赋值操作符,从而避免不必要的拷贝。上面push_back()会调用push_back(T&&)版本
A aObj(25); // lvalue
v.push_back(aObj);
aObj是左值,会调用push_back(const T&) 版本。
右值引用:https://www.jianshu.com/p/d19fc8447eaa
A && a=getTemp() //getTemp函数 返回值形参是 A ,实参是A(), 通过右值引用,可以让返回的临时A一直生存下去,生命期和a一样。
移动语义参考:
https://blog.csdn.net/wangshubo1989/article/details/49748703
移动语义可以避免不必要的拷贝,其实对象以引用方式传递就可以避免拷贝了。如果形参是非引用,那么传递右值(比如A())会引发移动构造函数(这个右值传递完就会丢弃 太浪费了 没有必要再拷贝) 避免不必要的拷贝,但是传递左值还是不会触发移动拷贝构造函数,会按原来的方式拷贝 可以强行加上std::move(aObj) 强行触发 但是要注意移动构造函数可能把传递的左值清空。
std::vector<int> GetNums() {
std::vector<int> nums;
nums.push_back(1);
nums.push_back(2);
return nums;
}
std::vector<int> result = GetNums(); //调用vector的移动拷贝构造函数,避免了拷贝
标准库的容器vector,string等实现了移动拷贝语义,所以这些容器作为函数的局部对象时都可以直接返回。
移动语义总结:类通过定义移动语义可以在需要移动场景的地方用它,从而避免一些不必要的拷贝。主要用在不用的话内存东西也扔了的情况,不用白不用,比如传递临时变量,返回局部对象。
基于移动语义和非移动语义的函数重载:push_back(T&&)和push_back(const T&)会区别对待传递过来的左值和右值,比如左值不改右值改。