安徽飞亚建设网站,网络推广的方法80种,wordpress网站变灰,建网站维护要多少钱右值引用#xff0c;顾名思义#xff0c;就是对一个右值进行引用#xff0c;或者说给右值一个别名。右值引用的规则和左值一用一模一样#xff0c;都是对一个值或者对象起个别名。
1. 右值引用和左值引用一样#xff0c;在定义的同时必须立即赋值#xff0c;如果不立即赋…右值引用顾名思义就是对一个右值进行引用或者说给右值一个别名。右值引用的规则和左值一用一模一样都是对一个值或者对象起个别名。
1. 右值引用和左值引用一样在定义的同时必须立即赋值如果不立即赋值语法错误看下面的例子
class A
{public:int m_val;A(int n):m_val(n) { }A(A a){m_vala.m_val;coutmove constructor is calledendl;}A operator(const Ar){if(this!r){m_valr.m_val;coutmove assignment operator is calledendl;}}~A(){coutDestructor is calledendl;}
};
int main(int argc, char const *argv[])
{A a(10); //定一个对象左值A lra; //左值引用同时赋值A rrmove(a); //定义右值引用同时赋值A rr2; //定义右值引用但是没有赋值rrwmove(a); //非法return 0;
} 2. 右值引用的操作和左值引用一样操作右值引用就是操作源对象本身因为右值引用就是源对象的一个别名。看下面的例子操作左值引用、右值引用、源对象中的任何一个其它两个都相应变化。
class A
{public:int m_val;A(int n):m_val(n) { }A(A a){m_vala.m_val;coutmove constructor is calledendl;}A operator(const Ar){if(this!r){m_valr.m_val;coutmove assignment operator is calledendl;}}~A(){coutDestructor is calledendl;}
};
int main(int argc, char const *argv[])
{A a(10); //定一个对象左值A lra; //左值引用同时赋值A rrmove(a); //定义右值引用同时赋值coutlr.m_vallr.m_val rr.m_valrr.m_val a.m_vala.m_valendl;coutchange value by original objectendl;a.m_val20;coutlr.m_vallr.m_val rr.m_valrr.m_val a.m_vala.m_valendl;coutchange value by left referenceendl;lr.m_val30;coutlr.m_vallr.m_val rr.m_valrr.m_val a.m_vala.m_valendl;coutchange value by right referenceendl;rr.m_val40;coutlr.m_vallr.m_val rr.m_valrr.m_val a.m_vala.m_valendl;coutleft reference and right reference wont create any new objectendl;return 0;
}
输出结果如下再次证明引用就是起别名 3. 从上图可以看出引用不会产生任何新的对象。
4. 右值引用和移动构造函数、移动赋值运算符没有任何关系。
5. 右值引用被正确赋值以后还能被二次赋值引用到一个新的对象上吗不能。右值引用一旦被定义随后的操作就对源对象的操作了。看下面这个例子
class A
{public:int m_val;A(int n):m_val(n) { }A(A a){m_vala.m_val;coutmove constructor is calledendl;}A operator(const Ar){if(this!r){m_valr.m_val;coutmove assignment operator is calledendl;}}~A(){coutDestructor is calledendl;}
};
int main(int argc, char const *argv[])
{A a1(10);A a2(20);A rfmove(a1);rfmove(a2); //不是对右值引用进行新的引用而是等价为a1move(a2)coutrf.m_valrf.m_val a2.m_val a2.m_valendl;a2.m_val30;coutrf.m_valrf.m_val a2.m_val a2.m_valendl;return 0;
}
rfmove(a2);不是二次引用而是等价为a1move(a2)因为rf就是a1这里一个移动赋值运算符被调用了 牢牢记住右值引用就是给右值纯右值、将亡值起个别名延长右值的生命周期没看到多大的使用价值。
另外定义右值引用的时候经常看到move函数但是右值引用和move没有任何关系move的作用是把一个左值强制转换为右值