欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 旅游 > C++左值与右值 将亡值 移动语义 完美转发 引用折叠

C++左值与右值 将亡值 移动语义 完美转发 引用折叠

2025/6/7 17:43:18 来源:https://blog.csdn.net/m0_73952999/article/details/145945139  浏览:    关键词:C++左值与右值 将亡值 移动语义 完美转发 引用折叠

 1.什么叫左值引用,什么叫右值引用?

右值引用是C++11引入的,与之对应C++98中的引用统称为左引用。左引用的一个最大问题就是,它不能对不能取地址的量(比如字面量常量)取引用。比如int &a = 1;就不可以。

为此专门定义了左值和右值,能取地址的都是左值,反之是右值。通过右值引用,可以增长变量的生命周期,避免分配新的内存空间.

并用&&来表示右值引用,这样就可以int &&a = 1;并用&来表示左值引用。

总结:左值引用只能绑定左值;右值引用只能绑右值,但常量左值引用可以绑字面量,比如const int &b = 10;已命名的右值引用,编译器会认为是一个左值;临时对象是左值。

引申问题:i ++和++i 有什么区别?(它返回值哪个是左值,哪个是右值)

i++是左值,并且可以赋值,i++是先返回i再去+1,是右值。而++i是先加再返回,返回的是增加过的,是可以左值

2.什么是将亡值,什么是纯右值

所谓纯右值就是临时变量或者字面值,将亡值是C++11新定义的将要被“移动”的变量,比如move返回的变量。

3.移动语义与完美转发

移动语义(move semantic):某对象持有的资源或内容转移给另一个对象。为了保证移动语义, 必须记得用std::move 转化左值对象为右值,以避免调用复制构造函数. 

完美转发(perfect forwarding): 为了解决引用折叠问题,必须写一个任意参数的函数模板,并转发到其他函数. 为了保证完美转发,必须使用std::forward, 我们希望左值转发之后还是左值,右值转发后还是右值.

4.什么是引用折叠?forward函数的原理

引用折叠就是,如果间接创建一个引用的引用,那么这些引用就会折叠。规则:

&& + &&->&& : 右值的右值引用是右值
&& + &->& : 右值的左值引用是左值
& + &&->& : 左值的右值引用是左值
& + &->& : 左值的左值引用是左值

为此引入了forward函数:

// 精简了标准库的代码,在细节上可能不完全正确,但是足以让我们了解转发函数 forward 的了
template<typename T>
T&& forward(T &param){return static_cast<T&&>(param);
}

传入 forward 实参是右值类型: 根据以上的分析,可以知道T将被推导为值类型,也就是不带有引用属性,假设为 int 。那么,将T = int 带入forward。param在forward内被强制类型转换为 int &&,还是右值引用。最终保持了实参的右值属性,转发正确

传入 forward实参是左值类型:根据以上的分析,可以知道T将被推导为左值引用类型,假设为int&。那么,将T = int& 带入forward。引用折叠一下就是 int &类型,转发正确。

5.什么是移动构造和移动赋值?

移动构造函数能直接使用临时对象已经申请的资源,它以右值引用为参数 ,拷贝以左值。

由于临时对象是右值,这里就需要使用一个move函数,它的作用的将左值强制转换为右值。

移动赋值是在赋值运算符重载的基础上,将对象右值引用作为形参进行拷贝或者赋值,从而避免创建新对象。

下面的例子展示了拷贝构造函数、赋值运算符重载、移动拷贝和移动赋值运算符重载,请仔细区别

class A{public://拷贝构造函数A(A& a) : x(a.x){cout << "Copy Constructor" << endl;}//赋值运算符A& operator=(A& a){x = a.x;cout << "Copy Assignment operator" << endl;return *this;}//移动拷贝A(A&& a) : x(a.x){cout << "Move Constructor" << endl;}//移动赋值A& operator=(A&& a){x = a.x;cout << "Move Assignment operator" << endl;return *this;}private:int x;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词