右值和右值引用学习笔记

张开发
2026/5/28 13:07:49 15 分钟阅读
右值和右值引用学习笔记
cpp新特性之右值右值和右值引用右值引用的作用以及使用未定引用类型的推导右值引用的传递右值和右值引用左值lvalue-loactorvalue :存储在内存中有明确存储地址可取地址的数据 右值rvalue-readvalue可以提供数据值的数据不可取地址intmain(){//左值intnum9;//左值引用intanum;//右值//右值引用intb8;//常量左值引用constintcnum;constintfb;//ok,右值引用来初始化常量左值引用constintgd;//欧克常量右值引用来初始化常量左值引用//常量右值引用constintd6;constintee;//errorintfb;//error//可见右值引用只能用右值初始化(纯右值或者将亡值)}右值引用的作用以及使用#includeiostreamusingnamespacestd;intvalue520;classTest{public:Test(){cout调用构造函数endl;coutm_num地址m_numendl;}Test(constTesta):m_num(newint(*a.m_num)){cout调用拷贝构造函数endl;}//移动构造函数-复用其他对象中的堆内存//m_num,浅拷贝Test(Testa):m_num(a.m_num){a.m_numnullptr;cout调用移动构造函数endl;}~Test(){cout调用析构函数endl;deletem_num;}int*m_num;};TestgetObj(){Test t;returnt;}TestgetObj1(){returnTest();//这个临时对象不能被取地址因此使用匿名对象}TestgetObj2(){returnTest();}//getObj1和getObj2返回的对象都是是右值纯右值将亡值将亡值即将被释放的不能取地址的临时对象或者是std::move的返回值intmain(){//要求右侧的对象是一个临时对象才会调用移动构造函数//如果没有定义移动构造函数会调用拷贝构造函数Test tgetObj();coutendl;Testt1getObj();coutm_num地址t1.m_numendl;//如果没有移动构造函数使用右值引用初始化要求更高这个临时对象不能被取地址Testt2getObj1();//这种方式复用了匿名对象的所有资源coutm_num地址t2.m_numendl;return0;}未定引用类型的推导在c中并不是所有的情况都代表右值引用在模板T ( const T 表示右值引用)在自动类型推导auto 这两种情况下为 未定引用类型通过右值推导T或者 auto得到的是 右值引用 类型 通过非右值右值引用左值左值引用常量右值引用常量左值引用推导 T或者 auto得到 左值引用类型右值引用的传递includeiostreamusingnamespacestd;voidprintValue(inti){//左值引用coutl_valueiendl;}voidprintValue(inti){//右值引用coutr_valueiendl;}voidforward(intk){//右值引用传递了导致k变成了一个左值类型(具名化)printValue(k);//因此这个函数打印左值}intmain(){inti520;printValue(i);//l_value 520printValue(1314);//r_value 1314forward(1314);//l_value 1314retrun0;}1.左值和右值是独立于他们的类型的右值引用类型可能是左值也可能是右值2.编译器会将已经命名的右值引用视为左值将未命名的右值引用视为右值3.右值引用被推导或者被传递之后对应的就是一个左值或者右值

更多文章