第十三章 拷贝控制

  1. 在定义任何 C++ 类时,拷贝控制操作都是必要部分。如果我们不显示定义这些操作,编译器也会为我们定义,但编译器定义的版本的行为可能并非我们所想。
  2. 拷贝初始化不仅在我们用=定义变量时会发生,在下列情况下也会发生:
        ① 将一个对象作为实参传递给一个非引用类型的形参;
        ② 从一个返回类型为非引用类型的函数返回一个对象;
        ③ 用花括号列表初始化一个数组中的元素或一个聚合类中的成员。
  3. 重载运算符本质上是函数,其名字有 operator 关键字后接表示要定义的运算符的符号组成。因此,赋值运算符就是一个名为 operator= 的函数。
  4. 某些运算符,包括赋值运算符,必须定义为成员函数。如果一个运算符是一个成员函数,其左侧运算对象就绑定到隐式的 this 参数。
  5. 在一个析构函数中,首先执行函数体,然后销毁成员。成员按照初始化顺序的逆序销毁。
  6. 在一个析构函数中,不存在类似构造函数中初始化列表的东西来控制成员如何销毁,析构部分是隐式的。销毁类类型的成员需要执行成员自己的析构函数。内置类型没有析构函数,因此销毁内置类型成员什么也不需要做。
  7. 隐式销毁一个内置指针的成员不会 delete 它所指向的对象。而智能指针是类类型,所以具有析构函数。
  8. 如果一个类需要自定义析构函数,几乎可以肯定它也需要自定义拷贝赋值运算符和拷贝构造函数。
  9. 对于析构函数已删除的类型,不能定义该类型的变量或释放指向该类型动态分配对象的指针。
  10. 如果一个类有数据成员不能默认构造、拷贝、复制或销毁,则对应的成员函数被定义为删除的。
  11. 希望阻止拷贝的类应该使用 =delete 来定义它们自己的拷贝构造函数和拷贝赋值运算符,而不应该将它们声明为 private 。
  12. 当你编写赋值运算符时,有两点需要记住:
        ① 如果将一个对象赋予它自身,赋值运算符必须能正确工作;
        ② 大多数赋值运算符组合了析构函数和拷贝构造函数的工作。
        (当你编写一个赋值运算符时,一个好的模式是先将右侧运算对象拷贝到一个局部临时对象中。)
  13. 与拷贝控制成员不同, swap 并不是必要的。但是,对于分配了资源的类,定义 swap 可能是一种很重要的优化手段。
  14. 使用拷贝和交换的赋值运算符自动就是异常安全的,且能正确处理自赋值。
  15. 返回左值引用的函数,连同赋值、下标、解引用和前置递增/递减运算符,都是左值的表达式的例子。返回非引用类型的函数,连同算数、关系、位及后置递增/递减运算符,都生成右值。
  16. 左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的临时对象。(右值引用所引用的对象将要被销毁,或者该对象没有其他用户)
  17. 变量是左值,因此我们不能将一个右值引用直接绑定到一个变量上,即使这个变量时右值引用类型也不行。
  18. 除非标准库知道我们的移动构造函数不会抛出异常,否则它会认为移动我们的类对象时可能会抛出异常,并且为了处理这种可能性而做一些额外的工作。
  19. 不抛出异常的移动构造函数和移动赋值运算符必须标记为 noexcept 。
  20. 除非 vector 知道元素类型的移动构造函数不会抛出异常,否则在重新分配内存的过程中,它就必须使用拷贝构造函数而不是移动构造函数。
  21. 在移动操作之后,移后源对象必须保持有效的、可析构状态,但是用户不能对其值进行任何假设。
  22. 如果一个类定义了自己的拷贝构造函数、拷贝赋值运算符或析构函数,编译器就不会为它合成移动构造函数和移动赋值运算符了。
  23. 只有当一个类没有定义任何自己版本的拷贝控制成员,且它的所有数据成员都能移动构造或移动赋值时,编译器才会为它合成移动构造函数或移动赋值运算符。
  24. 如果移动操作可能被定义为删除的函数,编译器就不会合成它们。
  25. 定义了一个移动构造函数或移动赋值运算符的类必须也定义自己的拷贝操作,否则,这么成员默认地被定义为删除的。
  26. 移动右值,拷贝左值,但如果没有移动构造函数,右值也被拷贝。(可以将 && 转换为 const &)
  27. 所有五个拷贝控制成员应该看做一个整体:一般来说,如果一个类定义了任何一个拷贝控制操作,它就应该定义所有五个操作。
  28. 除了构造函数和赋值运算符外,如果一个成员函数同事提供拷贝和移动版本,它也能从中受益。
  29. 对于 & 限定的函数,我们只能将它用于左值;对于 && 限定的函数,只能用于右值。
  30. 如果一个成员函数有引用限定符,则具有相同参数列表的所有版本都必须有引用限定符。
  31. 调用 move 隐含地承诺我们将不会再使用移后源对象,除了销毁它或赋予它一个新值之外。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值