virtual destructor for pure abstract class [duplicate]
Asked Answered
W

7

5

Based on what I found here and on other links on stackoverflow, we should always define a virtual destructor in the base class if we plan to use it polymorphically. I want to know if there is an exception to this rule.

I have seen production code that does not define virtual destructor for the pure abstract base classes and in one of cppcon 2014 video Accept no visitor, around 10:06 the BoolExp struct defined is a pure abstract class and has no virtual destructor.

So for a pure abstract class defined like this

  class Base {
      public:
         virtual foo() = 0;
         virtual bar() = 0;
     }

My question is it absolutely must that we define a virtual destructor for "Base" class, even though it does have any data members? Are there any exceptions to the virtual destructor rule?

Thanks in advance.

Best, RG

Wordy answered 30/7, 2019 at 15:48 Comment(4)
It is possible but not recommended. In cases where lifetime of object is not managed by pointer to base class this is not needed, but I would do it anyway.Hollah
You need a virtual destructor if you are going to delete polymorphically. See https://mcmap.net/q/45050/-when-to-use-virtual-destructors/10077Adiana
It probably was left off the slides in order to save space.Prole
hmm. That must be the case. Thanks for your helpWordy
P
7

My question is it absolutely must that we define a virtual destructor for "Base" class, even though it does have any data members?

It depends. If you have a case like

base * foo = new child(stuff);
// doing stuff
delete foo;

then you absolutely must have a virtual destructor. Without it you'll never destroy the child part.

If you have a case like

child * foo = new child(stuff);
// doing stuff
delete foo;

Then you do not need a virtual destructor, as child's will be called.

So the rule is if you delete polymorphically, you need a polymorphic (virtual) destructor, if not, then you don't

Parnell answered 30/7, 2019 at 15:57 Comment(0)
D
1

The exception to the rule is if you never delete an object through a pointer to the base class. In that case the base class destructor does not need to be virtual.

But if you ever delete an object via a base class pointer, then the base class destructor must be virtual or your program has Undefined Behaviour.

Digestive answered 30/7, 2019 at 15:55 Comment(0)
M
1

My question is it absolutely must that we define a virtual destructor for "Base" class, even though it does have any data members?

Stricktly speaking, No.

However, whether the base class has any member variables is not relevant. If the destructor gets called using a pointer to the base class, your code has undefined behavior regardless of whether the base class has any member variables or not.

Are there any exceptions to the virtual destructor rule?

If you are able to manage lifetimes of derived classes in such a way that the call to delete the objects is done via derived class pointers, you don't invoke undefined behavior and your code will be well behaved, assuming everything else is in your code base is in good order.

Muggins answered 30/7, 2019 at 15:57 Comment(0)
I
1

we should always define a virtual destructor in the base class if we plan to use it polymorphically.

You should always define a virtual destructor in a base classs if we plan to delete it polymorphically through that base class.

Now, one problem is that "I don't intend to" isn't safe; you should make it impossible.

Make the destructor virtual (and empty), or make it protected (and empty). A protected destructor makes polymorphic deletion unlikely (it can be bypassed, but only through pretty insane means).

Barring that, you have to be careful. This is one of the reasons why inheriting from (say) std vector is a thing to be wary of.

Immolate answered 30/7, 2019 at 16:12 Comment(0)
C
0

Deleting a derived class object using a pointer to a base class that has a non-virtual destructor results in undefined behavior. 

Otherwise you are ok to not to have virtual destructor.

Cousteau answered 30/7, 2019 at 15:51 Comment(0)
K
0

is it absolutely must that we define a virtual destructor for "Base" class, even though it does have any data members? Are there any exceptions to the virtual destructor rule?

It is not a must. It's a good habit that can prevent bugs.

If you decide to create a base class that doesn't have a virtual destructor, it is the responsibility of you, the developer, to always ensure that derived objects are deleted as the correct type or as a base type that does have a virtual destructor.

Krummhorn answered 30/7, 2019 at 15:55 Comment(0)
T
0

I would like to make an important (at least, in my view) practical amendment to correct answers describing the deletion through base object.

In particular, the destructors are called non-virtually if object life-time is managed through std::shared_ptr<Base> allocated via

std::shared_ptr<Base> sptr = std::make_shared<Derived>(args);
Twi answered 30/7, 2019 at 16:0 Comment(2)
We got issue at job by promoting std::shared_ptr to std::unique_ptr with class with missing virtual destructor....Particularism
@Particularism I would call it a 'demoting'. But I understand you.Twi

© 2022 - 2024 — McMap. All rights reserved.