22

我有大量继承自基类(标准)的继承类(标准)。这criterion是代码

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;
};

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

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\n");
    };
};

由于我这里根本没有析构函数,但这应该是一个基类,我是否需要插入一个空的虚拟析构函数,即像这样?:

virtual void ~criterion() = 0;

如果需要该虚拟析构函数声明,是否所有中间类也需要一个?即上面的fastFilter是否也需要一个虚拟析构函数?

4

4 回答 4

51

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

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

于 2009-05-05T22:31:50.593 回答
31

建议插入:

virtual ~criterion() {}

从 C++11 开始,您可以使用= default;而不是空 body {}

这是为了避免从基类的指针中删除问题。否则你会泄漏内存,因为派生类的析构函数不会被调用。

criterion *c = new fastFilter();
delete c; // leaks
于 2009-05-05T22:32:19.017 回答
13

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

virtual ~criterion() { }

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

于 2009-05-05T22:34:01.570 回答
7

与其他人已经回答的一个小变化:

代替

virtual void ~criterion() = 0;

所需的版本是:

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

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

于 2009-05-06T04:34:34.123 回答