Consider this:
class FluffyThing
{
public:
FluffyThing()
{
m_pMyFur = new Fur;
}
virtual ~FluffyThing();
protected:
Fur * m_pMyFur;
};
class ClawedFluffyThing : public FluffyThing
{
public:
ClawedFluffyThing()
: FluffyThing()
{
m_pMyClaws = new Claws;
}
virtual ~ClawedFluffyThing();
protected:
Claws * m_pMyClaws;
};
class ScaryFluffyThing : public ClawedFluffyThing
{
public:
ScaryFluffyThing()
: ClawedFluffyThing()
{
m_pMyTeeth = new Teeth;
m_pMyCollar = new SpikedCollar;
}
virtual ~ScaryFluffyThing();
protected:
Teeth * m_pMyTeeth;
SpikedCollar * m_pMyCollar;
};
Hopefully there are not too many mistakes in that – I think you get the idea. The essential point is there are 3 class with an IS-A relationship between them, and each class also HAS-A attribute or two that is going to require some cleanup when it comes to destruction time. If I had not declared the virtual destructors, would the compiler have generated the following for me automatically? Having declared the destructors, and therefore being forced to implement them (assuming the classes are used) is what follows the correct long-hand way to do the destruction?
FluffyThing::~FluffyThing()
{
delete m_pMyFur;
}
ClawedFluffyThing::~ClawedFluffyThing()
{
delete m_pMyClaws;
FluffyThing::~FluffyThing();
}
ScaryFluffyThing::~ScaryFluffyThing()
{
delete m_pMyTeeth;
delete m_pMyCollar;
ClawedFluffyThing::~ClawedFluffyThing();
}
There is bound to be a definitive answer out there already… but I couldn’t lay my hands on it quick enough for my likes.
No. You don’t manually call the destructors of base classes, they are called automatically, in reverse order of inheritance. Other than that, it’s fine.
Of course, you wouldn’t even need the
deletes if you used RAII (smart pointers instead of raw pointers).No. 🙂
virtualdestructors are there for correct behaviour in the case you delete a derived class instance through a base class pointer. The following:is legal only if
FluffyThing‘s destructor is virtual. Otherwise, it’s undefined behaviour.