(1)派生类中的拷贝构造函数
如果派生类中定义了自己的拷贝构造函数,那么该函数中应该显示调用基类的拷贝构造函数来初始化基类部分:
1 class Derived : public Base 2 { 3 public: 4 Derived(const Derived& d) 5 : Base(d) 6 { } 7 };
如果省略了上面代码中的第5行,那么将在该派生类拷贝构造函数中调用基类的默认构造函数初始化基类部分,结果导致派生类成员是从d中拷贝过来的,而基类部分却是默认值,这与拷贝应该拷贝整个对象的初衷是违背的。
(2)派生类中的赋值构造函数
同拷贝构造函数一样,派生类定义中应在自己的赋值构造函数中显示的调用基类的赋值构造函数:
1 Derived &Derived::operator=(const Derived &rhs) 2 { 3 if(this != rhs) 4 { 5 Base::operator=(rhs); 6 //... 7 } 8 return *this; 9 }
(3)派生类中的析构函数
派生类的构造函数中会首先调用基类的构造函数来初始化基类部分,但是派生类的析构函数并不会调用基类的析构函数来撤销基类的成员,这是由编译器显式调用基类析构函数来完成的,每个析构函数只负责销毁自己的成员。与构造函数相反,编译器会首先运行派生类析构函数,然后依次往上调用各基类的析构函数。
通常,基类中的析构函数应为虚函数,因为程序中指针的静态类型和动态类型可能不同:静态类型为基类指针,动态类型为派生类对象。此时要删除真正的对象就应调用派生类的析构函数而非静态类型基类的析构函数,为了实现这个目的——根据动态类型确定要调用的析构函数,就应在基类中将析构函数设为virtual类型,即使该析构函数的函数体是空的。
析构函数的虚函数性质会像其他虚函数一样被继承,继承层次中的基类中几乎都应该定义一个虚析构函数。