如果一个类继承自纯基类,那么什么是默认析构函数?

时间:2011-04-19 11:53:27

标签: c++ inheritance language-lawyer

考虑接下来的两个课程:

struct Base
{
  virtual ~Base()
  {
  }

  virtual void foo() = 0;
};

struct Derived : public Base
{
  virtual void foo()
  {
  }
};

以下是导致未定义的行为:

Base *obj = new Derived;
delete obj;

附加问题:如何将一个方法声明为虚拟,它在派生类中是虚拟的(即使虚拟关键字未在派生类中使用),但对于析构函数则不然?

4 个答案:

答案 0 :(得分:4)

  

以下是导致未定义的行为:

不,这不是正确地调用未定义的行为 ,因为Base的析构函数是virtual


编辑:这只是为了澄清一个疑问(在下面的评论中提出),并强调我上面所说的。

@Oli Charlesworth评论道:

  

从技术上讲,即使它没有被声明为虚拟,行为也会未定义,这只是不受欢迎的。

没有。行为将是未定义的。

标准中的第5.3.5 / 3节说明,

  

在第一种选择中(删除   对象),如果是静态类型的   操作数与其动态不同   类型,静态类型应为基础   操作数的动态类型的类   而静态类型应该有一个   虚析构函数或行为   未定义。在第二个备选(删除数组)中的动态类型   要删除的对象与其静态类型不同,行为未定义。

我认为这有助于消除疑虑。: - )

答案 1 :(得分:2)

这不是未定义的行为。您已将基类析构函数声明为virtual,因此在运行时,delete obj将首先调用Derived中的“默认”析构函数(因为您尚未明确声明一个),然后是Base中的析构函数。

答案 2 :(得分:1)

对于任何类,构造函数和析构函数都不是继承的。这在标准中规定。因此,您的代码不会导致未定义的行为,因为它将调用该类的默认构造函数/析构函数。
正是由于这个原因,继承性不适用于析构函数/构造函数。从父对象继承构造函数/析构函数是没有意义的,因为此对象可能具有所有形式的不同成员。

答案 3 :(得分:1)

由于您已将基类的析构函数声明为虚拟,因此此处没有未定义的行为。

陈述:

Base *obj = new Derived;
delete obj;

将导致调用派生类的析构函数,然后调用Base类的析构函数。我没有得到第二个问题