C++ Primer——拷贝控制

1、如果一个构造函数的第一个参数是自身类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数。一般情况下,合成的拷贝构造函数会将其参数的成员逐个拷贝到正在创建的对象中。编译器从给定对象中依次将每一个非static成员拷贝到正在创建的对象中。

2、每个成员的类型会决定其如何拷贝:对类类型成员来说,会使用其拷贝构造函数来拷贝;对内置类型的成员则直接拷贝。

3、拷贝初始化通常使用拷贝构造函数来完成。

4、拷贝初始化不仅在使用“=“定义变量时发生,在下列情况也会发生

  • 将一个对象作为实参传递给一个非引用类型的形参;
  • 从一个返回类型为非引用类型的函数返回一个对象;
  • 用花括号列表初始化一个数组中的元素或一个聚合类中的成员;
  • 某些类类型还会对它们所分配的对象使用拷贝初始化。例如,初始化标准库容器或是调用其insert或push成员时,容器会对其元素进行拷贝初始化。与之相对,用emplace成员创建的元素都进行直接初始化。

5、决定一个类是否要定义它自己版本的拷贝控制成员时,一个基本原则是首先确定这个类是否需要一个析构函数,如果一个类需要一个析构函数,几乎可以肯定它也需要一个拷贝构造函数和一个拷贝赋值运算符。

6、如果一个类需要一个拷贝构造函数,几乎可以肯定它也需要一个拷贝赋值运算符,反之亦然。然而,无论是需要拷贝构造函数还是需要拷贝赋值运算符都不必然意味着也需要析构函数。

7、可以通过将拷贝构造函数和拷贝赋值运算定义符定义为删除的函数来阻止拷贝。删除的函数为:虽然声明了它们,但是不能以任何方式来使用它们。在函数的参数列表后面加上=delete来指出我们希望将它定义为删除的,且=delete必须出现在函数第一次声明的时候。我们也可以对任何函数指定=delete(我们只能对可以合成的默认构造函数或拷贝控制成员使用=default)。但值得注意的是,析构函数不能是删除的成员。

8、拷贝控制成员:拷贝构造函数和拷贝赋值运算符。

9、通常,管理类外资源的类必须定义拷贝控制成员。因为这种类通常需要通过析构函数来释放对象所分配的资源,一旦一个类需要析构函数,那么它几乎肯定也需要一个拷贝构造函数和一个拷贝赋值运算符。

10、通常类直接拷贝内置类型(不包括指针)成员;这些成员本身就是值,因此通常应该让它们的行为像值一样,如何拷贝指针成员决定了类是具有类值行为还是类指针行为。

11、编写赋值运算符需要注意的两点:

  • 如果将一个对象赋予它自身,赋值运算必须能正确工作;
  • 大多数赋值运算符组合了析构函数和拷贝构造函数的工作。
  • 编写赋值运算符好的模式是先将右侧运算对象拷贝到一个局部临时对象中,当拷贝完成后,销毁左侧运算对象的现有成员就是安全的了。一旦左侧运算对象的资源被销毁,就只剩下将数据从临时对象拷贝到左侧运算对象的成员中了。
发布了14 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Luncles/article/details/104477930