C++primer 第十三章笔记 初稿

13.1 拷贝,赋值和销毁

  1. 拷贝构造函数

    • 定义:是构造函数,且第一个参数是自身类类型的引用,且任何额外参数都有默认值

    • 即使定义了其他构造函数,编译器也会合成拷贝构造函数,其操作为逐个拷贝到正在创建的对象中。

    • 发生情况:

    • 用=运算符定义变量
    • 向形参传递非引用的实参
    • 返回一个非引用类型的对象
    • 花括号列表初始化一个数组或聚合类

    • explicit 限制会对初始化方式产生较大影响。

      注:在容器操作中,insert或push会造成拷贝初始化,而emplace进行直接初始化。

  2. 拷贝赋值运算符

    • 编译器会合成拷贝赋值运算符。

    • 合成拷贝运算符有时可以禁止对该类型的对象赋值。

  3. 析构函数

    • 合成析构函数有时被用来阻止该类型的对象被销毁。
    • 析构函数自身不直接销毁类的成员。
  4. default与delete

    • default:要求编译器生成合成版本(隐式声明为内联)
    • delete:声明但不能被使用(默认合成的有时不合理)

    • 如果析构函数是删除的,则这类对象无法被定义但可以被动态分配。

    • 若类的某个成员的析构函数是删除的或private,则该类的合成拷贝构造函数为删除的;

    • 若类的某个成员有一个const或引用成员,则该类的拷贝赋值运算符为删除的;

    • 若类的某成员的析构函数是删除的或private,或有一个const成员且该成员无类内初始化器或显示定义的默认构造函数,则该类的默认构造函数是删除的;

    • 类的成员的某部分是删除的,则该类的对应部分也是删除的;

    • 区别:default可以出现在非第一次声明的地方,但delete不行。同时任何函数都可以被声明为delete

13.2 拷贝控制与资源管理

定义拷贝操作时,考虑拷贝类值还是类指针,是一种好的角度。

  1. 类值行为
    注:通常赋值运算符综合了拷贝构造函数与析构函数操作,且自定义赋值必须有效解决自赋值问题;
  2. 类指针行为
    注:应当在设计中考虑引用计数的问题,可以用shared_ptr代替

13.3 交换

  1. 一般类的swap操作声明为inline;
  2. 赋值运算中用swap与值传递的方法,是十分安全的。

    A &operator = (A ra){
    swap (*this, ra);
    return *this;
    }

13.4 对象移动

  1. 右值引用

    • 标志:&&
    • 性质:
      • 绑定到一个将要销毁的对象上(逻辑上将要销毁,即不会再使用)
      • 不能将一个右值引用绑定到一个右值引用类型的变量
    • 将右值引用绑定到左值上的办法
      • 强制类型转换
      • 调用move函数
    • 移动操作类似于“窃取了”移后源对象的值,让它成为了一个“空壳”。
  2. noexcept

    • 含义:承诺不抛出异常。
    • 要求:如果分离编译,头文件和定义时都要注明。
  3. 移动操作的注意点

    • 参数是右值引用(废话)
    • 移动后必须保证源对象销毁无害
    • 移动是不可逆的
    • 在赋值中,对自赋值情况要事先判断
  4. 移动构造函数

    • 编译器只有在当前类无任何拷贝控制成员,且数据成员皆非静态时,才会合成移动构造函数。
    • 只有当用default()指令,要求编译器生成移动构造函数,但不满足生成要求时,移动函数被定义为删除的。
  5. 移动迭代器

    • 含义:改变一般迭代器的解引用运算符行为
    • 操作:make_move_interator
  6. 引用限定符

    • 作用:阻止右值调用该函数
    • 方式:形参列表后加&限定符
    • 性质:可以区分重载版本(与const限定符一样)

你可能感兴趣的:(C++,primer)