C ++中的虚拟默认析构函数

Virtual Default Destructors in C++

我有一大组继承的类(条件),它们继承自一个基类(条件)。这是criterion的代码

1
2
3
4
5
6
7
8
9
class criterion
{
public:
    virtual unsigned __int32 getPriorityClass() const = 0;
    virtual BOOL include(fileData &file) const = 0;
    virtual void reorderTree() = 0;
    virtual unsigned int directoryCheck(const std::wstring& directory) const = 0;
    virtual std::wstring debugTree() const = 0;
};

从这个派生类的一些例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class fastFilter : public criterion
{
public:
    void reorderTree() {};
    unsigned int  directoryCheck(const std::wstring& /*directory*/) const { return DIRECTORY_DONTCARE; };
    unsigned __int32 getPriorityClass() const { return PRIORITY_FAST_FILTER; };
};

class isArchive : public fastFilter
{
public:
    BOOL include(fileData &file) const
    {
        return file.getArchive();
    }
    std::wstring debugTree() const
    {
        return std::wstring(L"+ ISARCHIVE
"
);
    };
};

因为我在这里根本没有析构函数,但是这个应该是一个基类,我需要插入一个空的虚拟析构函数吗,比如这样?以下内容:

1
virtual void ~criterion() = 0;

如果需要虚拟析构函数声明,那么所有中间类也都需要一个吗?也就是说,上面的fastfilter也需要一个虚拟析构函数吗?


是的-基类需要一个虚拟析构函数,即使它是空的。如果不这样做,那么当某个delete通过基指针/引用成为派生对象时,派生对象的成员对象将无法正确地销毁自己。

派生类不需要声明或定义自己的析构函数,除非它们需要默认析构函数行为以外的其他东西。


建议插入

1
virtual ~criterion() {}

以避免删除基类指针问题。否则,您将泄漏内存,因为不会调用派生类的析构函数。

1
2
criterion *c = new fastFilter();
delete c; // leaks


您不需要使析构函数变为抽象的,只需给它一个空的实现:

1
virtual ~criterion() { }

这样就不必在每个子类中强制实现它,但它们中的每一个都将有一个(继承的)虚拟析构函数。


与其他人已经回答的问题相比,有一个小小的变化:

而不是

1
virtual void ~criterion() = 0;

所需版本为:

1
2
    virtual ~criterion() {}  //Note: Removed void as destructors not allowed
                             //  a return type

要了解有关虚拟析构函数的更多信息,请参阅常见问题解答中的此链接,何时我的析构函数应该是虚拟的?