覆盖析构函数C++

Dan*_*y A 8 c++ inheritance overriding destructor multiple-inheritance

从C++ FAQ:

[11.4]我可以为我的班级重载析构函数吗?没有.

我意识到这意味着你不能改变返回类型,参数的类型和参数的数量.我可能会分析单词的语法,但是可以覆盖 Parent的析构函数吗?

class Child : public Parent {
public:
    virtual Parent::~Parent() {
        // New definition
    }
};
Run Code Online (Sandbox Code Playgroud)

那个问题是递归吗?

class Grandchild : public Child {
public:
    Child::Parent::~Parent() {
        // An even newer definition
    }
};
Run Code Online (Sandbox Code Playgroud)

我已经阅读了这个相关的帖子,它让我思考,因为析构函数不是继承的,它们不能被覆盖,但我从未见过它明确陈述过.

编辑:我改变了这一点,以反映我想覆盖Parent的析构函数,注意Child和Grandchild重写~Parent().

我这样做的主要原因是在改变它的销毁方式时保持Parent的界面(子类的完整原因).我将拥有管理所有Parent的其他内容,并将在我选择的稍后时间显式调用它们的析构函数.

Kon*_*lph 8

我可能会分析单词的语法

不,你绝对不是 - 这是两件截然不同的事情.

但是有可能覆盖析构函数吗?

是的,实际上在很多情况下你必须这样做.为了使其适用于多态对象,您需要将基类析构函数声明为virtual:

Parent const& p = Child();
Run Code Online (Sandbox Code Playgroud)

p.~Child()在范围结束时正确调用,因为它Parent::~Parent是虚拟的.


Joh*_*ing 6

是的,可以覆盖类的析构函数.实际上,当您定义使用多态的类层次结构时,必须在基类中声明虚拟析构函数.

析构函数的覆盖与普通成员函数的覆盖完全相同,因为当您delete通过指向基类的指针销毁对象时,会正确调用派生类的析构函数.这就是为什么必须在基类中为多态层次结构设置虚拟析构函数.

但是,虚拟析构函数和虚拟成员方法之间存在差异,这与virtual析构函数的性质无关.也就是说,在执行这样的代码时:

class A
{
public:  
  virtual void Foo() {}
  virtual ~A() {};
};

class B : public A
{
public:
  void Foo() {};
  ~B() {}
};

int main()
{
  A* a = new B;
  a->Foo();  // B::Foo() is called
  delete a;  // B is destroyed via B::~B()
}
Run Code Online (Sandbox Code Playgroud)

...当你调用a->Foo(),该方法Foo()B被调用.既然B::Foo()没有明确调用A::Foo(),A::Foo()也没有调用.

然而,当对象通过破坏delete a;,第一析构函数B::~B()被调用,则该完成之后,但在控制返回到程序中,所述基类的析构函数A::~A()称为.

当然,当你考虑它时,这是显而易见的,而且这与virtual析构函数的性质无关,但它的行为与普通的virtual方法调用不同,所以我想我会指出它.

义务标准报价:

[C++ 03] 12.4/6:析构函数

在执行析构函数的主体并销毁在主体内分配的任何自动对象之后,类X的析构函数调用X的直接成员的析构函数,X的直接基类的析构函数,如果X是派生类最多的类型( 12.6.2),它的析构函数调用X的虚拟基类的析构函数.调用所有析构函数,就好像它们是使用限定名称引用一样,即忽略更多派生类中的任何可能的虚拟覆盖析构函数.基础和成员按照构造函数完成的相反顺序销毁(见12.6.2).析构函数中的return语句(6.6.3)可能不会直接返回给调用者; 在将控制转移给调用者之前,调用成员和基础的析构函数.