新建一个类对象时,类的构造函数会对其初始化,许多时候需要使用一个已经存在的对象去复制出同类的一个或多个新对象,这个时候就需要使用到类的复制构造函数。有些情况需要同类对象之间互相赋值,就像A=B一样,这就是赋值函数的工作。当对象的作用域结束或动态分配的对象被删除时,就应自动调用析构函数释放对象获取的所有资源。复制构造函数是一种特殊的构造函数。具有单个形参,这个参数采用对象的引用的形式。赋值函数其实就是赋值操作符=。析构函数是构造函数的互补。
复制构造函数、赋值函数和析构函数总称为复制控制。当类没有自己定义这些操作,编译器会自动提供一套默认的复制控制函数以方便用户的使用。但编译器提供的复制控制函数非常精炼,它们只做一些必需的工作——默认复制构造函数只简单地复制类中每个数据成员的值,默认赋值函数与默认复制构造函数类似执行逐个成员赋值,默认析构函数则什么都不做。因此,对某些类而言,依赖于默认定义会导致灾难性的错误,尤其是在类具有指针成员或者类中使用到动态内存分配时,使用默认复制控制函数就只能做到浅拷贝。浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量的名称不同,那么对于指针,浅拷贝中仅仅是复制了指针变量的值,而并没有复制指针指向的数据,也即对其中任何一个对象的改动都会影响另外一个对象。这个时候就需要类定义自己的复制控制成员以实现深拷贝。深拷贝是指源对象与拷贝对象互相独立,改动任何一个对象的都不会对另外一个对象造成影响。
当程序中需要根据另一个同类型的对象显式或隐式初始化一个对象时,当函数的参数为类对象且采用值传递方式时,当函数的返回值是类对象时都需要使用到复制构造函数。撤销类对象时会自动调用析构函数,所以当函数的返回值是类对象时,在对象值传递完毕后就会自动调用析构函数。类对象参与表达式运算时,如A=B+C,在右值计算完毕赋值给左值时需要用到赋值函数。总体来说,如果一个类重载了运算符,那么在一个运算表达式中将需要使用到所有复制控制函数。根据“三法则”规则,如果类需要析构函数,则它也需要赋值操作符和复制构造函数。