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

河南省建设安全监督站的网站网络推广网址

河南省建设安全监督站的网站,网络推广网址,wordpress音乐主题推荐,wordpress 主题 首页前言 最近在看C Primer的时候,对于对象移动一直不太懂,所以在查找各种资料,仔细研究代码后,打算写篇博客记录下来,果然还是不要得过且过,看见不懂的就查,弄懂为止最好了。 对象移动 很多时候都会…

前言

最近在看C++ Primer的时候,对于对象移动一直不太懂,所以在查找各种资料,仔细研究代码后,打算写篇博客记录下来,果然还是不要得过且过,看见不懂的就查,弄懂为止最好了。

对象移动

很多时候都会发生对象拷贝,但是拷贝有个问题,对于有些仅仅做完拷贝就销毁的情况,其实没必要,更好的做法是进行移动元素;在新标准中,可以用容器保存不可拷贝的类型,前提是他能被移动即可;

右值引用

  1. 标准库容器、string和shared_str类既支持移动也支持拷贝,IO类和 unique _xstr 类可以移动但不能拷贝;

  2. 右值引用只能绑定到一个将要销毁的对象,通过 && 来获得右值引用;

  3. 右值引用:所引用的对象将要被销毁;对象没有其他用户;这些意味着右值引用的代码可以自由的接管所引用的对象的资源;

  4. 变量是左值,因此我们不能将一个右值引用直接绑定到一个变量上,但是常量可以,即使变量是右值引用类型也不可以;

    例子:

    int && rr1 = 42; //正确:字面意思是右值
    int && rr2 = rr1; //错误:表达式rr1是左值
  5. 调用了move函数就意味着承诺,不能对移动后对源对象的值做任何的假设,但是你可以销毁,也可以赋予它新值,就是不能使用一个移后源对象的值;

  6. 使用move的代码应该使用std:move而不是简单的move,这样做可以避免潜在的名字冲突;

    例子:

    int && rr3 = std::move(rr1);
    

移动构造函数和移动赋值运算符

  1. 和拷贝构造函数不同,移动构造函数不分配任何内存,在完成资源移动后,移动构造函数还需要确保移后源对象是否可以销毁掉,其必须不再指向被移动的资源,因为其资源的所有权已经归属到新创建的对象(如果对象中存在成员指针,则需要将其置为空);

    例子:

    Derived::Derived(Derived && d) noexcept: tag(d.tag){d.tag = "";
    }
    

    其中tag是Derived的成员属性;

  2. noexcept 是我们承诺一个函数不抛出异常的一种方法,在一个构造函数中,noexcept出现在参数列表和初始化列表开始的冒号之间(在类的声明和定义中都需要指定noexcept);

    (使用方法如上)

  3. 不能在使用右侧运算对象的资源之前就释放左侧运算对象的资源;在移动操作之后,移后源对象必须保持有效的、可析构的状态,但是客户不能对其进行任何假设;

    例子:

    Derived& operator=(const Derived& other) {if (this != &other) {name = other.name;tag = other.tag;}return *this;
    }
    

    注意:函数参数是引用类型的

  4. 和拷贝构造操作不同,如果一个类定义了自己的拷贝构造函数,拷贝赋值函数或者析构函数,编译器就不会为它合成移动构造函数和移动赋值运算符,则其就会使用拷贝操作替代移动操作;

    只有当一个类没有定义任何自己版本的拷贝控制成员,而且它的所有数据成员都能移动构造或移动赋值时,编译器才会为它合成移动构造函数和移动赋值运算符;

  5. 和拷贝操作不同,移动操作永远不会隐式定义为删除的函数;

    合成的移动操作定义为删除的函数遵循定义删除的合成拷贝类似原则:

    • (和拷贝构造函数不同)移动构造函数被定义为删除的函数的条件:有类成员定义了自己的拷贝构造函数并且未定义移动构造函数,或者又是有类成员未定义自己的拷贝构造函数并且编译器不能为其合成移动构造函数;

    • 如果有类成员的移动构造函数或移动赋值运算符被定义为删除的或是不可访问的,则类的移动构造函数或移动赋值运算符被定义为删除的;

    • (和拷贝构造函数类似)如果类的析构函数被定义为删除的或是不可访问的,则类的移动构造函数被定义为删除的;

    • (和拷贝赋值运算符类似)如果类成员是const的或者是引用,则类的移动赋值运算符被定义为删除的;


    下面这种情况是正确的,没有定义为删除的情况:

    class X {
    public:int i; // 内置类型可以移动string s; // string定义了自己的移动操作
    };class HasX {
    public:X ele; // X有何合成的移动操作
    };X x;
    X x2 = std::move(x); // 使用合成的移动构造函数
    HasX hx;
    HasX hx2 = std::move(hx); //使用合成的移动构造函数
    

    但是在列举的四种情况就是错的,移动操作则会被定义为删除的。

    注意:定义了一个移动构造函数或移动赋值运算符的类必须也定义自己的拷贝操作,否则,这些成员默认地被定义为删除的。

  6. 如果一个类既有移动构造函数,也有拷贝构造函数,编译器则会使用普通的函数匹配规则来确定会使用哪个构造函数,赋值也是类似;

  7. 如果一个类没有移动构造函数,那么函数匹配原则则会保证该类型的对象会被拷贝,即使试图通过调用move来移动也是如此;

    例子:

    class Foo {
    public:Foo() = default;Foo(const Foo&); //拷贝构造函数//并未定义移动构造函数
    };Foo f1;
    Foo f2(f1); //拷贝构造函数
    Foo f3(std::move(f1)); //拷贝构造函数,因为未定义移动构造函数
    

    注意:用拷贝操作代替移动操作是安全的,一般情况下,前者都会满足后者的要求;

  8. 拷贝并交换赋值运算符和移动操作

    同时实现移动构造函数和赋值运算符:

    class Person {
    public:// 添加的移动构造函数Person(Person && p) noexcept : name(p.name) {p.name = "";}// 赋值运算符既是移动赋值运算符,也是拷贝赋值运算符Person& operator=(Person p) {swap(*this, p);return *this;}private:string name;
    };
    

    赋值运算符会交换两个对象的指针以及成员,在swap之后,p的指针会指向this,而this则会指向p的内存,当p离开其作用域之后,其的成员也会被销毁,自然两者就会同时实现喽~;

转载于:https://www.cnblogs.com/George1994/p/6034698.html

http://www.lbrq.cn/news/2572381.html

相关文章:

  • 公司网站没做301怎么做301湘潭网页设计
  • 网站服务器可以更换吗百度直播平台
  • 湘潭电大网站品牌策划公司哪家好
  • 有没有做任务一样的网站兼职营销方案推广
  • 企业做网站维护如何做好精准营销
  • 网站做seo推广方案杭州seo推广排名稳定
  • 做网站公奇闻司郑州汉狮seo是什么品牌
  • it外包中心东莞搜索seo网站关键词优化
  • 装饰工程网站模板大数据营销平台那么多
  • 网站备案信息查询接口网址服务器查询
  • 营销型网站建设的特色百度问问首页登录
  • 网站建设前期准备方案广州网站制作实力乐云seo
  • 网站关键词长尾词南京seo报价
  • dw+如何做自适应网站外链服务
  • vb.net 网站开发关键字排名优化公司
  • 百度免费域名注册网站免费个人网站源码
  • 北京网站怎么建设东莞网站推广排名
  • 山东 网站建设seo关键词工具
  • 网站建设创新点seo新方法
  • 常用的html编辑器有哪些重庆网站排名优化教程
  • 做网站 服务器如何写好软文
  • 一个主机可以做几个网站广州百度网站排名优化
  • 营销型网站建设设定包括哪些方面网站的优化从哪里进行
  • 广告联盟做网站今日热点新闻头条排行榜
  • 有没有做网站兼职在线生成网站
  • 算卦网站哪里可以做模板建站网页
  • 重庆网站设计公司域名信息查询网站
  • 高职图书馆网站建设大赛企业培训方案
  • java可以做网站吗商丘搜索引擎优化
  • 九江 网站建设小说关键词生成器
  • LLM - 智能体工作流设计模式
  • Python-初学openCV——图像预处理(六)
  • 题单【模拟与高精度】
  • 在linux(ubuntu)服务器上安装NTQQ并使用
  • linux 启动流程?
  • 【05】OpenCV C#——OpenCvSharp 图像基本操作---转灰度图、边缘提取、兴趣区域ROI,图像叠加