【问题标题】:No virtual functions, but still need virtual destructor?没有虚函数,但还需要虚析构函数?
【发布时间】:2014-03-08 13:12:57
【问题描述】:

我写了一个没有虚函数的基类和派生类。 virtual 的使用通常是我看到的何时使用 virtual 析构函数的指南。

然而,虽然我的类没有虚函数,但我在传递它们时以多态方式使用这些类。所以Base类应该实现一个虚析构函数吗?

class Base;
class Derived;

main()
{
   base& baseVar = derived();
   foo(baseVar);
}

【问题讨论】:

  • 只有当你要delete指向基类的指针时才使用虚拟析构函数。那是你唯一需要的时候。如果您不打算以这种方式删除,那么请保护基类的析构函数以防止错误。
  • “使用 virtual 是典型的指南”——这是一个有用的经验法则,但真正的指南是您是否需要多态销毁(例如通过指向基类的指针删除)。

标签: c++ virtual-destructor


【解决方案1】:

没有多态性,因为您使用引用来调用(将调用)非虚拟函数。也就是说,在您的示例中,您只需调用(将调用)基类的函数。

还有这个说法

base& baseVar = derived();

不应编译,因为您将临时对象与非常量引用绑定。

应该有

const base& baseVar = derived();

至于您示例中的析构函数,则不需要虚拟析构函数。因为您定义了对派生类的临时对象的引用。在这种情况下,临时对象将被称为自己的析构函数。即首先调用基类的析构函数(从派生类的析构函数中),然后执行派生类的析构函数体。

如果您要在堆中分配派生内存并将分配内存的地址分配给基类的指针,则需要使用 vertual 析构函数。当您为此指针调用 operator delete 时,如果您没有虚拟析构函数,则将调用基类的唯一析构函数。

例如

class Base;
class Derived;

main()
{
   base* baseVar = new derived();
   delete baseVar; // base shall have a virtual destructor
}

【讨论】:

  • 正如您所展示的,我的示例不需要多态破坏。但是,我不知道用户将如何使用我的课程。你的例子表明了这一点。这使我相信我应该通过提供或保护它来积极处理它。我不确定我将如何做出这个决定,但我认为任何一种方式都可以
【解决方案2】:

如果您的程序会发现自己处于将通过基类指针删除派生类的实例以确保调用正确的析构函数的位置,则您应该使用虚拟析构函数。

查看这个问题了解更多详情When to use virtual destructors?

【讨论】:

  • “你可能最终会......”但你可能不会。这还不足以要求不能以多态方式使用的类具有虚拟析构函数。
  • @juanchopanza 好的,我会改写
猜你喜欢
  • 2012-04-18
  • 2012-04-13
  • 2021-06-01
  • 2010-09-12
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多