Home > other >  Why isn't there an implicit defaulted definition for pure virtual destructor?
Why isn't there an implicit defaulted definition for pure virtual destructor?

Time:10-24

I know that if the class is supposed to be abstract, but does not contain any used-defined method, there is technique to achieve this by making the destructor pure virtual.

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

As far as I understand the object in example below should not be able to be instantiated.

#include <iostream>

class A{
public:
    A(){std::cout<<"A::A()"<<std::endl;}
    virtual ~A() = 0;
};


class B : public A{
public:
    B(){std::cout<<"B::B()"<<std::endl;}
};

int main(){
    B b;
}

I know that pure virtual functions also can have definitions, and that in the case above it should be defined for destructor of B, but something is obscure to me. Is there any particular reason not to make the definition of pure virtual destructor to be implicitly defaulted in C standard, because to me it would make a lot of sense.

CodePudding user response:

If a function is declared pure virtual, then this means two things:

  1. The class with such a declaration cannot be instantiated.

  2. Any derived classes must provide a definition for the method, or they also cannot be instantiated.

However, #2 only happens if you don't provide a definition for that pure virtual function declaration. If you do define the pure virtual function, then derived classes do not specifically need to override those methods.

Therefore, if there was always a defaulted definition of a pure virtual destructor, it would be impossible to force a user to declare a destructor for derived classes.

In the vanishingly rare circumstance where you have a class you intend to use as a virtual type, but has no actual interface (I fail to see how you could uphold the Liskov substitution principle when you have no interface) and therefore should not be instantiated, and but you also want a user to not have to define a destructor explicitly, you can do this:

#include <iostream>

class A{
public:
    A(){std::cout<<"A::A()"<<std::endl;}
    virtual ~A() = 0;
};

A::~A() = default; //Yes, this is legal.


class B : public A{
public:
    B(){std::cout<<"B::B()"<<std::endl;}
};

int main(){
    B b;
}

However, I highly doubt this circumstance comes up in reality often enough to actually matter. In most real types intended for use in virtual interfaces, they have actual virtual interfaces beyond "can be destroyed". They need virtual destructors, but they also have other virtual functions which can be pure. As such, their destructors don't need to be pure.

  • Related