给出以下示例:
class BaseClass
{
BaseClass()
{
};
virtual ~BaseClass()
{
this->Cleanup();
};
virtual void Cleanup()
{
// Do cleanup here.
};
};
class Level1DerivedClass : public BaseClass
{
Level1DerivedClass()
{
};
virtual ~Level1DerivedClass()
{
};
virtual void Cleanup()
{
// Call my base cleanup.
BaseClass::Cleanup();
// Do additional cleanup here.
};
};
class Level2DerivedClass : public Level1DerivedClass
{
Level2DerivedClass()
{
};
~Level2DerivedClass()
{
};
void Cleanup()
{
// Call my base cleanup.
Level1DerivedClass::Cleanup();
// Do additional cleanup here.
};
};
main()
{
Level2DerivedClass * derived2 = new Level2DerivedClass();
delete derived2;
return 0;
}
当我删除派生类引用时,我将 EXPECT 流程如下:
发生的事情是,它正在按我期望的方式为每个继承级别(1-3)调用析构函数。但是,当从BaseClass析构函数调用this-> Cleanup()时,它仅执行自己的实现。我不明白为什么会这样,因为通常在实例化派生类指针,将其转换为基类指针并从基类指针调用虚拟方法(在本例中为“this”)时,它仍然运行派生类的实现(整个“虚拟”点,是吗?)。在我的示例中,永远不会调用Level2DerivedClass::Cleanup和Level1DerivedClass::Cleanup。
我以这种方式进行设置的原因是,我希望能够调用我的清理代码而不必破坏我的对象,这就是为什么我要从实际的析构函数主体中抽象出来。
如果您对采取更适当的方法有任何建议,我非常高兴。但是我也想解释一下为什么我的设置不起作用-我误会了什么?
预先感谢您的宝贵时间。
最佳答案
经验法则是:Never Call Virtual Functions during Construction or Destruction。
他们的行为不像您预期的那样。随着每个析构函数的完成,this
的动态类型将得到有效修改。在C++标准的[class.cdtor]中: