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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/827196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:28:45  来源:igfitidea点击:

Virtual Default Destructors in C++

c++virtual-destructor

提问by Billy ONeal

I've got a large set of inherited classes (criteria) which inherit from a base class (criterion). Here's criterion's code

我有一大组继承自基类(标准)的继承类(标准)。这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;
};

Some examples of derived classes from this one:

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

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

Since I don't have a destructor here at all, but yet this is supposed to be a base class, do I need to insert an empty virtual destructor, I.e. like this?:

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

virtual void ~criterion() = 0;

If that virtual destructor declaration is needed, do all intermediate classes need one as well? I.e. would fastFilter above need a virtual destructor as well?

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

回答by Michael Burr

Yes - the base class needs a virtual destructor, even if it's empty. If that is not done, then when something delete's a derived object through a base pointer/reference, the derived object's member objects will not get a chance to destroy themselves properly.

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

Derived classes do not need to declare or define their own destructor unless they need something other than default destructor behavior.

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

回答by Filip Fr?cz

The recommendation is to insert

建议是插入

virtual ~criterion() {}

to avoid the deletion off a base class pointer problem. Otherwise you will leak memory as derived classes' destructors will not be called.

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

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

回答by sth

You don't need to make the destructor abstract, just give it a empty implementation:

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

virtual ~criterion() { }

This way you are not forced to implement it in every child class, but still each of them will have a (inherited) virtual destructor.

这样你就不会被迫在每个子类中实现它,但每个子类仍然会有一个(继承的)虚拟析构函数。

回答by aJ.

One small change from what others have already answered:

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

Instead of

代替

virtual void ~criterion() = 0;

the required version is:

所需的版本是:

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

To know more about virtual destructor have a look at this link from FAQ When should my destructor be virtual?

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