【问题标题】:Pure virtual destructor in C++C++中的纯虚析构函数
【发布时间】:2010-10-12 11:17:33
【问题描述】:

写错了吗:

class A {
public:
    virtual ~A() = 0;
};

对于抽象基类?

至少在 MSVC 中编译...它会在运行时崩溃吗?

【问题讨论】:

  • 它可以编译,但它是否链接?

标签: c++ polymorphism destructor pure-virtual


【解决方案1】:

是的。你还需要实现析构函数:

class A {
public:
    virtual ~A() = 0;
};

inline A::~A() { }

应该足够了。

既然这得到了反对票,我应该澄清一下:如果你从 A 派生任何东西然后尝试删除或销毁它,A 的析构函数最终将被调用。由于它是纯粹的并且没有实现,因此会出现未定义的行为。在一个流行的平台上,这将调用 purecall 处理程序并崩溃。

编辑:将声明修复为更符合,使用http://www.comeaucomputing.com/tryitout/编译

【讨论】:

  • 嗯,是的。纯只是意味着派生类也需要提供实现。
  • 实现纯虚函数其实是合法的。对于提供默认实现但强制子类显式调用它非常有用。
  • MSN 并注意如果您在标题中有该定义,则需要在其前面放置“内联”以避免违反 ODR(一个定义规则)
  • 为什么 A::~A() 必须明确定义,因为我认为每个对象都有一个默认析构函数?与任何类型的继承一样,总是调用析构函数链,而不必总是定义基类析构函数。
  • 更好的说法是,一旦你声明了析构函数,它就不会自动为你实现。
【解决方案2】:

私有析构函数:当您创建派生类的对象时,它们会给您一个错误——否则不会。不过可能会出现诊断信息。

12.4 析构函数

6 析构函数可以声明为虚拟(10.3)或纯虚拟(10.4);如果在程序中创建了该类或任何派生类的任何对象,则应定义析构函数。

具有纯虚析构函数的类是抽象类。 请注意:

10.4 抽象类

2 纯虚函数仅在使用或如同使用 (12.4) 限定 ID 语法 (5.1) 调用时才需要定义。

[注意:函数声明不能​​同时提供纯说明符和定义——结束 注意]

直接取自草稿:

struct C {
   virtual void f() = 0 { }; // ill-formed
};

【讨论】:

  • +1。我认为 Herb Sutter 对此也有一些很好的信息:gotw.ca/gotw/031.htm。有趣的是,任何纯虚函数都可能提供了一个实现,而不仅仅是析构函数。
  • 是的,这是你在面试中用来吓唬你的面试官的事情;)
  • 根据我的经验,这实际上并不少见。
  • @Neil Butterworth:哪一个?
  • @Dirk - “任何功能”场景。发现它用于实现一些常见行为的情况并不少见。
猜你喜欢
  • 2016-10-13
  • 2012-07-14
  • 2011-03-03
  • 2020-01-25
  • 2014-12-20
  • 2017-09-09
  • 2010-11-16
相关资源
最近更新 更多