C++中的纯虚析构函数

Posted

技术标签:

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

写错了吗:

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

对于抽象基类?

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

【问题讨论】:

它可以编译,但它是否链接? 【参考方案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 - “任何功能”场景。发现它用于实现一些常见行为的情况并不少见。

以上是关于C++中的纯虚析构函数的主要内容,如果未能解决你的问题,请参考以下文章

局部抽象类的纯虚析构函数

C++11接口纯虚析构函数

C++中的各种“虚“-- 虚函数纯虚函数虚继承虚基类虚析构纯虚析构抽象类讲解

C++中的各种“虚“-- 虚函数纯虚函数虚继承虚基类虚析构纯虚析构抽象类讲解

C++ 虚析构和纯虚析构

C++ --- 虚析构和纯虚析构