Virtual Default Destructors in C++

不打扰是莪最后的温柔 提交于 2019-12-29 17:45:04

问题


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

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?


回答1:


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.

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




回答2:


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



回答3:


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.




回答4:


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?



来源:https://stackoverflow.com/questions/827196/virtual-default-destructors-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!