第15章 面向对象编程(10)
15.4.4 虚析构函数
删除指向动态分配对象的指针时,需要运行析构函数在释放对象的内存之前清除对象。处理继承层次中的对象时,指针的类型可能与被删除对象的动态类型不同,可能删除实际指向派生类对象的基类类型指针。
如果删除基类指针,则需要运行基类析构函数并清除基类的成员,如果对象实际是派生类型的,则没有定义该行为。要保证运行适当的析构函数,基类中的析构函数必须为虚函数。
如果析构函数为虚函数,那么通过指针调用时,运行哪个析构函数将因指针所指对象类型的不同而不同。
像其他虚函数一样,析构函数的虚函数性质都将继承。因此,如果层次中根类的析构函数为虚函数,则派生类析构函数也将是虚函数,无论派生类显式定义析构函数还是使用合成析构函数,派生类析构函数都是虚函数。
基类析构函数是三法则的一个重要例外。三法则指出,如果类需要析构函数,则类几乎也确定需要其他复制控制成员。基类几乎总是需要析构函数,从而将析构函数设为虚函数。如果基类为了将析构函数设为虚函数而具有空析构函数,那么,类具有析构函数不表示也需要赋值操作符或复制构造函数。
即使析构函数没有工作要做,继承层次的根类也应该定义一个虚析构函数。
构造函数和赋值操作符不是虚函数
在复制控制成员中,只有析构函数应定义为虚函数,构造函数不能定义为虚函数。构造函数是在对象完全构造之前运行的,在构造函数运行的时候,对象的动态类型还不完整。
虽然可以在基类中将成员函数operator=定义为虚函数,但这样做并不影响派生类中使用的赋值操作符。每个类有自己的赋值操作符,派生类中的赋值操作符有一个与类本身类型相同的形参,该类型必须不同于继承层次中任意其他类的赋值操作符的形参类型。
将类的赋值操作符设为虚函数很可能会令人混淆,而且不会有什么用处。
15.4.5 构造函数和析构函数中的虚函数
构造派生类对象时首先运行基类构造函数初始化对象的基类部分。在执行基类构造函数时,对象的派生类部分是未初始化的。实际上,此时对象还不是一个派生类对象。
撤销派生类对象时,首先撤销它的派生类部分,然后按照构造顺序的逆序撤销它的基类部分。
为了适应这种不完整,编译器将对象的类型视为在构造或析构期间发生了变化。在基类构造函数或析构函数中,将派生类对象当作基类类型对象看待。
构造或析构期间的对象类型对虚函数的绑定有影响。
如果在构造函数或析构函数中调用虚函数,则运行的是为构造函数或析构函数自身类型定义的版本。
摘自 xufei96的专栏
补充:软件开发 , C++ ,