Pure Virtual Destructor in C++

Why do we need a pure virtual destructor in C++?

  1. Probably the real reason that pure virtual destructors are allowed is that to prohibit them would mean adding another rule to the language and there's no need for this rule since no ill-effects can come from allowing a pure virtual destructor.

  2. Nope, plain old virtual is enough.

If you create an object with default implementations for its virtual methods and want to make it abstract without forcing anyone to override any specific method, you can make the destructor pure virtual. I don't see much point in it but it's possible.

Note that since the compiler will generate an implicit destructor for derived classes, if the class's author does not do so, any derived classes will not be abstract. Therefore having the pure virtual destructor in the base class will not make any difference for the derived classes. It will only make the base class abstract (thanks for @kappa's comment).

One may also assume that every deriving class would probably need to have specific clean-up code and use the pure virtual destructor as a reminder to write one but this seems contrived (and unenforced).

Note: The destructor is the only method that even if it is pure virtual has to have an implementation in order to instantiate derived classes (yes pure virtual functions can have implementations).

struct foo {
virtual void bar() = 0;
};

void foo::bar() { /* default implementation */ }

class foof : public foo {
void bar() { foo::bar(); } // have to explicitly call default implementation.
};

Pure virtual destructor in C++

Yes. You also need to implement the destructor:

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

inline A::~A() { }

should suffice.

And since this got a down vote, I should clarify: If you derive anything from A and then try to delete or destroy it, A's destructor will eventually be called. Since it is pure and doesn't have an implementation, undefined behavior will ensue. On one popular platform, that will invoke the purecall handler and crash.

Edit: fixing the declaration to be more conformant, compiled with http://www.comeaucomputing.com/tryitout/

C++11 interface pure virtual destructor

The difference between I1 and I2*, as you pointed out, is that adding = 0 makes the class abstract. In fact, making the destructor pure virtual is a trick to make a class abstract when you don't have any other function to be pure virtual. And I said it's a trick because the destructor cannot be left undefined if you ever want to destruct any derived class of it (and here you will), then you still need to define the destructor, either empty or defaulted.

Now the difference between empty or defaulted destructor/constructor (I21 and I22) is way more obscure, there isn't much written out there. The recommended one is to use default, both as a new idiom to make your intentions clearer, and apparently, to give the compiler a chance for optimization. Quoting msdn

Because of the performance benefits of trivial special member functions, we recommend that you prefer automatically generated special member functions over empty function bodies when you want the default behavior.

There are no visible differences between the two, apart from this possible performance improvement. = default is the way to go from C++11 on.

Why a pure virtual destructor needs an implementation

The compiler tries to build the virtual table given a virtual (pure or not) destructor, and it complains because it can't find the implementation.

virtual destructors differ from other virtual functions because they are called when the object is destroyed, regardless of whether it was implemented or not. This requires the compiler to add it to the vf table, even if it's not called explicitly, because the derived class destructor needs it.

Pedantically, the standard requires a pure virtual destructor to be implemented.

virtual destructor for pure abstract class

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

Default pure virtual destructor

In order to define a pure virtual method, you need a separate definition from the declaration.

Therefore:

struct X {
virtual ~X() = 0;
};

X::~X() = default;

Abstract class object and pure virtual destructor

We cannot make the object of the abstract class

This means that an abstract class cannot be instantiated by itself. It does not mean that objects of abstract class cannot be instantiated as part of a derived object, though: an instance of any derived class is also an instance of its abstract base.

This is where the destructor comes in: if you need one to free private resources allocated in the constructor of the abstract class, the only place to put the clean-up is its destructor.

Is it necessary to make the destruct pure virtual for an abstract class?

It is not necessary to mark the destructor pure virtual. You do it only if you define no other functions that could be marked pure virtual. In any event, you must provide an implementation for the destructor, even if you mark it pure virtual.

C++ Error when using virtual destructor

The problem is

virtual ~ISolution() = 0;

the destructor is not implemented.
Try

virtual ~ISolution() { }

instead.

This is needed even when only instances of the derived class are created, because destructors are special.
In a normal function, the base class implementation needs to be called explicitly, like

void Derived::Foo() {
Base::Foo();
....
}

but for a destructor, this is always done automatically.

why we are not obliged to implement pure virtual destructor?

why we are not obliged to implement the pure virtual base's destructor in our derived class?

Because destructors are not overridden.

To help remember that, think about the names: ~Base and ~Derived are not the same. Constructors and destructors, instead of working through overriding, are instead called in a chain: the bottom-most destructor runs and then it calls its parent destructor which then runs and then calls its parent destructor etc.

And that is why you must provide the body for a destructor if you want to delete an instance of one of the derived classes, even if it's marked as pure virtual: it needs a body to invoke when reaching it in the destructor chain.

So, what's the deal with virtual destructors to start with? It's done so that the compiler would know to invoke the bottom-most destructor when it encounters a destruction of some class. So destruction does use the virtual table, it's just that it's running the parent class destructor after the derived destructor is done, so it's not standard overriding.

does it mean as long as C++ adds to us four member functions by default: constructor, copy constructor, assignment and Destructor we don't need to implement it in our derived class?

Didn't quite understand the question, but in any case default-added methods are not created pure virtual and can be created in every class in an inheritance chain.

Virtual destructor for pure abstract base classes

Whereas, clang generates warning for:

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

using = default doesn't trigger it.

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

Even if both are valid.

Demo



Related Topics



Leave a reply



Submit