4
votes

Consider the following code snippet:

class A
{
virtual void function();
public:
  virtual ~A() {};
}

class B: public A
{
virtual void function() override final;
public:
  /*virtual*/ ~B() {}; // does this d-tor have to be declared at all?
}

I can find the info regarding the base class destructor easily, e.g. http://en.cppreference.com/w/cpp/language/destructor

"Deleting an object through pointer to base invokes undefined behavior unless the destructor in the base class is virtual. A common guideline is that a destructor for a base class must be either public and virtual or protected and nonvirtual"

A virtual destructor in a base class is a must, how about the derived class's destructors, do they have to be explicitly declared/defined? I find it quite confusing, since the destructors of the derived classes are automatically virtual too. Is it legal in terms of vtable addressing to skip the derived class's destructor's declaration/definition? What about the following situation:

class A
{
virtual void function();
public:
  virtual ~A() {};
}

class B: public A
{
virtual void function() override;
public:
  /*virtual*/ ~B() {}; // does this d-tor have to be declared at all?
}

class C: public B
{
virtual void function() override final;
public:
  /*virtual*/ ~C() {};  // does this d-tor have to be declared at all?
}
3
C++ doesn't force you to write code that doesn't do anything. You'll have to wean yourself off final, that could only be a macro that pretends that C++ has something to do with Java. Override is a valuable C++11 addition. Just not on a destructor, you can't fumble it like you can another virtual method. Write sane C++ code and everything falls together easily.Hans Passant

3 Answers

6
votes

There is no need to define explicitly destructors in derived classes. According to the C++ Standard

If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly-declared) is virtual

Also if you bother about the access control then

An implicitly declared destructor is an inline public member of its class.

The compiler will place the address of its implicitly defined destructor in vtable. So vtable for derived classes will store addresses of destructors of derived classes.

For readability of your code you could write for example

class B: public A
{
virtual void function() override final;
public:
  virtual ~B() = default;
}
3
votes

No, it does not need to be declared; classes that inherit from classes with a given function declared to be virtual do not need to declare their inherited form to be virtual for it to be virtual. This includes destructors which are implicitly declared.

1
votes

As others have stated, no, you don't need to declare a do-nothing destructor in descendent classes because it carries down from the ancestor class.

However, keep in mind that your class C might be derived from some third-party library class B in something like VendorBAwesomeness.dll, and B might in turn be derived from Microsoft's class A in mswonderful.dll.

If you want to be nice to the readers and users of your class, you should consider specifying virtual in your class C because you saw it in the interface for class B when you read about it, and the author of class B did the same when he/she learned about class A.

By passing this information down, you're allowing others to see clearly what your code does without them having to hunt around for the information.