接口的虚拟析构函数

Cla*_*bel 10 c++ polymorphism

接口是否需要虚拟析构函数,或者是自动生成的一个?例如,以下两个代码段中哪一个最好,为什么?请注意,这些是整个班级.没有其他方法,变量等.在Java中,这是一个"接口".

class Base
{
public:
    virtual void foo() = 0;
    virtual ~Base() {}
};
Run Code Online (Sandbox Code Playgroud)

要么...

class Base
{
public:
    virtual void foo() = 0;
    ~Base() {} // This line can be omitted, but included for clarity.
};
Run Code Online (Sandbox Code Playgroud)

编辑由于"不是我想要的"答案:

确切地说,每条路线的后果是什么.请不要给出模糊的答案,例如"它不会被破坏".请告诉我到底会发生什么.我有点装配书呆子.

编辑2:

我很清楚,"虚拟"标签意味着如果通过指向派生的指针删除析构函数将不会被调用,但(我认为)这个问题最终归结为"省略该析构函数是否安全,因为它是真是微不足道?"

编辑3:

我的第二次编辑只是完全错误和虚假信息.请阅读实际聪明人的评论以获取更多信息.

Jus*_*ier 13

考虑以下情况:

   Base *Var = new Derived();
   delete Var;
Run Code Online (Sandbox Code Playgroud)

您需要虚拟析构函数,否则在删除时Var,永远不会调用派生类的析构函数.

  • 不,*你*倒退了.在`Base`中缺少虚拟析构函数意味着当删除类型为`Base*`的指针时,*only*`Base :: ~Base`将被调用.如果`Base`析构函数*是*virtual,那么派生的析构函数也会被调用. (3认同)
  • @wowus:*Base*没有值得一提的析构函数.你不知道Derived的析构函数是做什么的. (2认同)
  • 你错过了这里的关键点.除非你将Base :: ~Base声明为虚拟,否则不会调用`Derived :: ~Derived`. (2认同)

小智 7

如果通过C++中的基类指针删除派生类对象,则结果是未定义的行为.UB是你真正想要避免的,所以你必须给基类一个虚拟析构函数.引用C++标准,第5.3.5节:

如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义.