Unimportant
Unimportant

Reputation: 2096

Is the C++ core guideline C35 "A base class destructor should be either public and virtual, or protected and nonvirtual" wrong for interface classes?

Say I have the following interface class in order to "Write to interfaces, not implementations":

class IDrawable
{
public:

    virtual void
    Draw() const = 0;

protected:

    ~IDrawable() = default;
};

Clients should not be able to delete dynamically allocated drawables trough a interface pointer so IDrawable's destructor is made protected and non-virtual, as per C++ Core guideline C.35: A base class destructor should be either public and virtual, or protected and nonvirtual.

Now for a class that implements this interface:

class CDrawable : public IDrawable
{
public:

    void
    Draw() const override;
};

This, off course, emits a warning:

CDrawable has virtual functions but non-virtual destructor.

To solve this we now have to add a virtual destructor to CDrawable. But it feels like a code smell to have a virtual destructor in a derived class, I've not seen that before (?) Wouldn't it make more sense to have a virtual protected destructor in IDrawable, contrary to what the guideline says?

Upvotes: 4

Views: 911

Answers (1)

Ulrich Eckhardt
Ulrich Eckhardt

Reputation: 17444

There is technically no issue. Your CDrawable has a public non-virtual destructor (implicitly defined). Invoking it doesn't cause undefined behaviour, unless of course it is invoked on a class derived from CDrawable. If you only have a reference to a IDrawable and invoked its destructor, you would skip destruction of the derived class (causing UB, I think), but since it's not publicly accessible, that is not a problem.

Yes, you get a warning. However, that warning is just that, an indication that something may be at fault. In this case, it isn't.

Upvotes: 2

Related Questions