拷贝构造函数
拷贝构造函数的第一个参数必须是一个引用类型。虽然我们可以定义一个接受非 const 引用的拷贝构造函数,但此参数几乎总是一个 const 的引用。
拷贝构造函数在几种情况下都会被隐式地使用。因此,拷贝构造函数通常不应该是explicit的(参见 7.5.4节,第 265 页)。
一般情况,合成的拷贝构造函数将其参数的成员逐个拷贝到正在创建的对象中(参见 7.1.5节,第 239 页)。编译器从给定对象中依次将每个非static成员拷贝到正在创建的对象中。
虽然我们不能直接拷贝一个数组(参见 3.5.1节,第 102页),但合成拷贝构造函数会逐元素地拷贝一个数组类型的成员。如果数组元素是类类型,则使用元素的拷贝构造函数来进行拷贝。
拷贝初始化通常使用拷贝构造函数来完成。但是,如我们将在13.6.2节(第473页)见,如果一个类有一个移动构造函数,则拷贝初始化有时会使用移动构造函数而非拷贝造函数来完成。
但现在,我们只需了解拷贝初始化何时发生,以及拷贝初始化是依靠拷构造函数或移动构造函数来完成的就可以了。
拷贝初始化不仅在我们用=定义变量时会发生,在下列情况下也会发生
- 将一个对象作为实参传递给一个非引用类型的形参
- 从一个返回类型为非引用类型的函数返回一个对象
- 用花括号列表初始化一个数组中的元素或一个聚合类中的成员(参见7.5.5节,第266 页)
某些类类型还会对它们所分配的对象使用拷贝初始化。例如,当我们初始化标准库容器或是调用其 insert 或 push 成员(参见 9.3.1 节,第 306 页)时,容器会对其元素进行拷贝初始化。
与之相对,用 emplace 成员创建的元素都进行直接初始化(参见9.3.1节,第308 页)。
--《C++ Primer》 p441
析构函数
合成的规则和拷贝构造函数比较类似。
什么时候会调用析构函数
无论何时一个对象被销毁,就会自动调用其析构函数:
- 变量在离开其作用域时被销毁。
- 当一个对象被销毁时,其成员被销毁。
- 容器(无论是标准库容器还是数组)被销毁时,其元素被销毁。
- 对于动态分配的对象,当对指向它的指针应用删除运算符时被销毁(参见12.1.2节,第409页)。
- 对于临时对象,当创建它的完整表达式结束时被销毁。
--《C++ Primer》 p445