Virtual destructors and override

Started by
9 comments, last by alvaro 5 years, 7 months ago

I just read a tutorial about destructors and virtual counterparts. Generally if I understood correctly every class that will potentially be inherited needs to have a virtual destructor. This is because if we use a pointer to a base class that the most recent class in inheritance can be freed and deallocated.

In my code I tried to implement this and as I did for other virtual member functions that I have, I added "override" keyword to a inherited destructor. As I did that Visual Studio started to complain after which I removed it.
If we use override keyword for virtual methods isn't it logic to use it for the destructor too?

Advertisement

Addung override to your inherited destructors is a good idea. The compiler will error if the base class is not using a virtual destructor, and should pass successfully if the base class has a virtual destructor. If you are seeing any other behavior then the compiler might be non-conformant. (I hope it's not the case)

Strange, if I keep a destructor defined in a class header than I cant use override keyword. I have to move the definition into .cpp to add the keyword.
I tried this on ordinary member functions and they can compile successfully with override keyword if they are defined in a class header.

6 hours ago, ryt said:

Strange, if I keep a destructor defined in a class header than I cant use override keyword. I have to move the definition into .cpp to add the keyword.
I tried this on ordinary member functions and they can compile successfully with override keyword if they are defined in a class header.

What's wrong? The below code compiles fine in VS 2017.


struct A
{
   virtual ~A() {}
};

struct B : public A
{
   ~B() override {}
};

 

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

Can you post some code? For instance, I fail to reproduce the problem with this:


#include <iostream>

struct X {
  virtual ~X() {
    std::cout << "Start ~X\n";
  }
};

struct Y : X {
  ~Y() override {
    std::cout << "Start ~Y\n";
  }
};

int main() {
  X *x = new Y();
  delete x;
}

 

On 9/26/2018 at 1:30 PM, ryt said:

I just read a tutorial about destructors and virtual counterparts. Generally if I understood correctly every class that will potentially be inherited needs to have a virtual destructor. 

Not quite. You only need to override a virtual destructor, in a subclass if there is some work to be done during destruction. So if you just say added a couple of integers in a subclass, even if you may inherit from that subclass there is no need to include a destructor for it. Only the most basal class in the tree that you intend to call delete from, needs a virtual destructor. Another thing is virtual distructors are different from other virtual functions as they automatically chain. The subclass destructors get called first and then you work your way back down to the root class(es).  You can call delete from a pointer to any class in the tree. It shouldn't matter.

I just went to paste some code, while doing so I tried to do the same thing as yesterday and now the code compiles ?. I must have been trying to override wrong destructor the whole time.
Sorry, I feel so stupid now ?. Thanks for the help.

8 hours ago, Gnollrunner said:

Not quite. You only need to override a virtual destructor, in a subclass if there is some work to be done during destruction.

 

The sentence you were responding to was this:

Quote

Generally if I understood correctly every class that will potentially be inherited [from] needs to have a virtual destructor. 

That is exactly right, except he might have missed the word "from" that I added in square brackets. If you write a class that is intended to be used as a base class and you don't declare its destructor virtual, a derived class that has non-trivial work to do during destruction may not get its destructor called when a pointer to base is deleted.

Was this just a language issue, or do we disagree on something? I am not sure...

 

28 minutes ago, alvaro said:

 

The sentence you were responding to was this:

That is exactly right, except he might have missed the word "from" that I added in square brackets. If you write a class that is intended to be used as a base class and you don't declare its destructor virtual, a derived class that has non-trivial work to do during destruction may not get its destructor called when a pointer to base is deleted.

Was this just a language issue, or do we disagree on something? I am not sure...

 

Well it depends how you think of it. Say C inherits from B and B inherits from A, and A has a virtual destructor.  B is a base class of C and can "potentially be inherited [from] " and in fact is inherited from, yet it doesn't need a virtual destructor. Hence I said " Only the most basal class in the tree that you intend to call delete from, needs a virtual destructor". Is this your understanding? If not, one of us is wrong.

Oh, the way I think about it I would say that B has a virtual destructor even if you didn't write one. So I believe we agree.

This topic is closed to new replies.

Advertisement