当前位置: 首页 > news >正文

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;
}

相关文章:

  • 爬虫技术结合淘宝商品快递费用API接口(item_fee):电商物流数据的高效获取与应用
  • 【无人机与无人车协同避障】
  • Element Plus 的 Form 组件表单验证指南
  • 使用 ubuntu
  • docker利用docker-compose-gpu.yml启动RAGFLOW,文档解析出错【亲测已解决】
  • 大模型训练微调技术介绍
  • 软考中级数据库思维导图
  • 【音视频】RGB、YUV基础
  • GCC RISCV 后端 -- GCC 后端框架的一些理解
  • Html5学习教程,从入门到精通,HTML 5 图像语法知识点语法知识点及案例代码(9)
  • AWS VPC行业解决方案:构建安全、灵活的企业云网络
  • Spring项目中常用操作记录
  • 因子分析讲解
  • C++类与对象:银行管理系统项目实战开发LeetCode每日一题
  • 【Web前端开发】---HTML标签及标签属性
  • 云计算中的“按需扩展”和“自动扩展”有何不同?
  • Ubuntu20.04双系统安装及软件安装(七):Anaconda3
  • pnpm+monorepo实现前端公共函数、组件库
  • 千兆网络测试仪使用全解析:从线序检测到性能压测实战
  • MySql基础以及安装
  • 全国 做网站的企业/广州seo关键词优化外包
  • 泸州市规划建设局网站/网络广告发布
  • 有那些专门做职业统计的网站/苏州疫情最新情况
  • 广安市城乡建设规划局网站/成人技术培训学校
  • python做网站好不好/b站推广入口2023
  • 网站设计有哪几种设计方法/最近新闻头条