views:

1056

answers:

4

Hello all :)

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?

Thanks all!

Billy3

+11  A: 

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.

Michael Burr
+13  A: 

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
Filip
Is there any reason to use an empty destructor over a pure virtual one?
Billy ONeal
Nevermind... answered by someone else :)
Billy ONeal
+8  A: 

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.

sth
+4  A: 

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?

aJ