Why default destuctor for an abstract class is not virtual?
Asked Answered
C

3

8

Consider

class A
{
public:
   virtual void foo () = 0;
};

At this point it is absolutely obvious that A is an abstract class and will never be instantiated on it's own. So why the standard doesn't demand that automatically generated destructor must be virtual as well?

I ask myself this question every time I need to define a dummy virtual desctuctor in my interface classes and can't see why the commetee did't do this.

So the question: why generated destructor in an abstract class is not virtual?

Crankshaft answered 14/11, 2012 at 18:46 Comment(6)
Abstract classes don't have to have virtual destructors.Chaconne
@PeteBecker Abstract classes must have either virtual destructors or protected destructors. No other choice. Am I right?Gregoire
@Gregoire -- 1) an abstract class is defined as a class that has at least one pure virtual function. 2) Any base class needs a virtual destructor if the design calls for deleting objects of a derived type through a pointer to that base type. 3) Some people think it's a good idea to make a non-virtual destructor protected, but that is not required by the language.Chaconne
@PeteBecker if the destructor of the base class is marked as neither a virtual function nor a protected function. Then the user of such classes must not assign a dynamically created instance of the derived class to the pointer of the base class.Otherwise, there would be a memory leak. Am I right?Gregoire
@Gregoire -- no. The only issue that a virtual destructor addresses is deleting an object of a derived type through a pointer to the base. As long as you don't do that, your code can traffic in pointers to the derived type and to the base type as much as it likes. void f(Base*p); void x() { Derived d; f(&d); } is perfectly okay as long as f doesn't delete p;.Chaconne
@PeteBecker Though it's perfectly okay as long as f doesn't delete p;, you know that p must be deleted sooner or later by your program, otherwise there would be a memory leak since you don't delete it. How do you think about it?Gregoire
F
8

Because in C++ you don't pay for what you don't need, and a virtual destructor adds overhead (even in already polymorphic classes) that isn't needed in many cases. For example you might not need polymorphic destruction and choose to have a protected destructor instead.

Further, as an alternative scenario, imagine that you have a class with a virtual method that does desire polymorphic destruction. Now imagine that the other virtual method is no longer needed and removed but polymorphic destruction is still needed. Now you have to remember to go back and add a virtual destructor or suffer undefined behavior.

Finally I think it would be hard to justify changing the default virtualness of the destructor (and it alone) based on whether a class is polymorphic or not rather than always and consistently making a destructor non-vurtual unless requested otherwise.

Forlorn answered 14/11, 2012 at 18:48 Comment(13)
I have to say watching the timing of this and Pete's comment pop up within about 2 seconds of each other made me laugh.Gustie
True, but on the other hand, how many such cases are there? Wouldn't it be logical to have it virtual by default and let programmer define it non-virtual when he really needs it?Crankshaft
@aleguna Then you'd add it overhead to every single class and struct everywhere, which is awful for C compatibility and for the baseline efficiency of any system that's entirely based on subtype polymorphism. There are a lot of useful classes and structs which don't need virtual, or any inheritance at all while we're at it.Henbit
@delnan, I'm talking about classes that are explicitly abstract, i.e. have pure virtual functions.Crankshaft
@aleguna Oh, okay (you may want to state this more explicitly in the question). Then this answer does not really apply, and nor does the other one, as the overhead is already there. Still, it's not unanimously good: It adds yet another nontrivial implicit rule. God knows C++ has enough of those already.Henbit
@delnan This answer still applies, because even a class with abstract bases is not always intended to be destroyed by deleteing a base pointer and making the base destructor virtual would make any derived destructors virtual as well. So even if some overhead is already there, adding additional overhead is not always the best idea.Herbertherbicide
@delnan: some overhead is already there; adding a virtual destructor increases that overhead, and the cost of destruction, which might be undesirable.Blacksmith
@ChristianRau You can argue with semantics (overlooked that, admittedly), but this answer is exclusively about overhead.Henbit
@delnan Yes, that's what I'm saying. The answer perfectly applies because it talks about the additional overhead a virtual destructor would create, and is completely correct in this.Herbertherbicide
@ChristianRau I consider the points you raise (makes unexpected deleting by base pointer legal, forced derived destructors to be virtual) primarily correctness/semantic issues. While it also implies a performance cost for destructor calls, any semantic difference overrules any performance consideration IMHO -- unless, of course, one decides that the other semantics are okay too.Henbit
@delnan If author of class A never intends his users to do delete p (where p is A*) then he might prefer to make the destructor protected. In that case having a virtual as default makes little sense. So, I think choice is just left to the author as the options are many. Apart from that, it would be unnatural (against the spirit of the langauge) to declare ~A() just to override a default virtual ~A() provided by the lanaguage if virtual had been the default.Hypsometry
@delnan In your and my opinion maybe, but not in the opinion of C++'s don't-pay-for-what-you-don't-use philosophy. And of course there are cases where the other smenatics (deleting by pointer to base with non-virtual destructor) are, well, still not okay, but completely out of question anyway.Herbertherbicide
@Mark B What do you mean by "already polymorphic classes"? Could you please explain that in more detail for me?Gregoire
B
0

A virtual Destructor would cause dereferencing every time this class would be destructed. Rather small overhead, but C++ wants to save as much time as possible. Anyway, being explicit is always better, than trusting implicit compiler magic. C++'s motto: "Trust the programmer".

LG ntor

Borstal answered 14/11, 2012 at 18:58 Comment(1)
The question is specifically about abstract classes, which are already polymorphic. The extra memory cost would be one entry in a vtable that already exists.Blacksmith
K
0

When the c++ standard was written, it was written by keeping in my mind that it will be used on various platforms. Some of which might has memory constraints.By adding virtual-ism we are increasing the overhead.That why at that time every method/dtor needs to be explicitly made virtual by the programmer, whenever we do require polymorphism.

Now question comes to why can not standard c++ implementation of abstract class default destructor. Dont you think it will strange to have different implementation, and also it will cause confusion.And what about the case(however small it is) , when you dont need the distructor to be virtaul(so as to save memory).Why waste the memory

Katlaps answered 3/5, 2013 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.