C++ Primer 中文版 学习笔记(十二)

第13章复制控制

1        复制构造函数、赋值操作符和析构函数总称为复制控制。

2        一种常见的情况需要类定义自己的复制控制成员是:类具有指针成员。(深拷贝、浅拷贝问题

3        三法则:如果类需要析构函数,则它也需要赋值操作符和复制构造函数。

例外:如果基类为了将析构函数设为虚函数而具有空析构函数,那么,类具有析构函数并不表示也需要赋值操作符和复制构造函数。

4        复制构造函数用于:

a)        根据另一个同类型的对象显式或隐式初始化一个对象
b)        复制一个对象,将它作为实参传给一个函数
c)         从函数返回时复制一个对象
d)        初始化顺序容器中的元素
e)        根据元素初始化列表初始化数组元素

5        C++支持两种初始化形式

a)        直接初始化(直接调用与实参匹配的构造函数)
b)        复制初始化(为了与C的用法兼容,总是调用复制构造函数)

步骤:首先使用指定构造函数创建一个临时对象,然后用复制构造函数将那个临时对象复制到车正在创建的对象。

6        必须定义复制构造函数的情况:(包含类类型或内置类型(非指针)成员的类,无须显式地定义复制构造函数,也可以复制

a)        有数据成员是指针或者有成员表示在构造函数中分配的其他资源
b)        或在创建新对象时必须做一些特定工作

7        为了防止用户代码复制类类型的对象,类必须显式声明其复制构造函数为private

此时,类的友元和成员仍可以进行复制,如果想要连友元和成员中的复制也禁止,就可以声明一个(private)复制构造函数但不对其定义。或者是使用想Uncopyable这样的base class也是一种做法。

弊端不允许复制的类对象只能作为引用传递给函数或从函数返回,它们也不能用作容器的元素。

Example:  IO类型对象,复制构造函数为private

8        动态分配的对象只有在指向该对象的指针被删除时才撤销。如果没有删除指向动态对象的指针,则不会运行该对象的析构函数,对象就一直存在,从而导致内存泄露,而且,对象内部使用的任何资源也不会释放。

只有删除指向动态分配对象的指针或实际对象(而不是对象的引用)超出作用域时,才运行析构函数。

9        大多数C++类采用以下三种方法之一管理指针成员:

a)        指针成员采取常规指针型行为。这样的类具有指针的所有缺陷,但无需特殊的复制控制
b)        类可以实现所谓的“智能指针”行为。指针所指向的对象时共享的,但类能够防止悬垂指针
c)         类采取值型行为。指针所指向的对象时唯一的,由每个类对象独立管理

10  无论类是否定义自己的析构函数,都会创建和运行合成析构函数。如果类定义了析构函数,则在类定义的析构函数结束之后运行合成析构函数。

没有更多推荐了,返回首页