NO, at least, it would be extremely surprising and weird. Just try and see. I bet you that if you have a proper compiler, it will issue a compilation error.

Why? Well it does not make any sense to have a pure virtual destructor. Because virtual destructors are not like normal virtual functions, they don't get overridden, they get extended in the derived classes. This is because each base class is responsible for cleaning up it's own data members (if they hold dynamically allocated memory or other resources like sockets or threads). When the class is derived, the author of the derived class should not be given the responsibility of reimplementing the destructor of the base class (what if he doesn't know how?). So, instead, the C++ standard prescribes that the destructors be called essentially in an upward order, i.e. from most derived to most basic class. This is true whether the destructor is virtual or not. The reason for virtual destructors is to make sure that, at run-time, the destructor of the most derived class is called first (via dynamic binding) and then that destructor will relay the destructor call to its base class(es). The ordering goes the other way for the constructor, i.e. the most basic class first then downwards to the most derived class constructor. The only exception is multiple virtual inheritance in which the order is a bit different.

Since you can only have one destructor (no parameter and no return type, so, no overloading) and that destructor is implicitly called upon deleting the object, there cannot be a class without a destructor. Of course, you can omit the destructor if none is needed (e.g. a POD class), but that simply tells the compiler to generate a default one (so there is still a destructor defined for the class even if you omit it). What you cannot do is give a declaration of the destructor and then provide no implementation (with, for example, the = 0; at the end), because that will inhibit the compiler from generating the default destructor while not providing an implementation for it.

>NO, at least, it would be extremely surprising and weird. Just try and see. I
>bet you that if you have a proper compiler, it will issue a compilation error.

If your compiler complains about a pure virtual destructor, either the compiler is non-standard, or your code is wrong.

>Why? Well it does not make any sense[...]
You're mistaking "pure virtual" with "no definition". While there's a restriction that pure virtual functions cannot have an inline definition:

virtual void foo() = 0 {} // Illegal syntax

There's no provision against defining a pure virtual function. In fact, such a definition is required if the function is called implicitly (as in the case of destructors), or explicitly. One example of an explicit call is the base class providing a default implementation and the derived class using it:

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

void base::foo() {}

class derived: public base {
public:
    void foo() { base::foo(); }
};

>Is there any concept of pure virtual destructor in C++?
Yes. As you should already know, base classes should generally have a virtual destructor. If you want the base class to be abstract (generally a good practice) but it doesn't have any pure virtual member functions, the destructor can be made pure. It's a convenient and common technique for making a base class abstract without unnecessarily forcing implementations in the derived class.

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

base::~base() {}

class derived: public base {};

int main()
{
    base *p = new derived();
    delete p;
}

Note that the derived class does not need to explicitly define a destructor if the base class has a pure virtual destructor. The default implicit destructor will suffice as an implementation (thus becoming virtual rather than pure virtual) and the derived class will be concrete.

@Narue:
Well I guess we have different nomenclature, I consider a function as pure virtual (or abstract, as a remnant of my Delphi days) only if there is: 1) "= 0;" at the declaration and 2) no implementation anywhere (if you put it next to the derived class definition or anywhere else doesn't make a difference to me, it is no longer a pure virtual method or destructor). So in my view, I'm still right ;) it does make sense for a destructor to have either no definition or no compiler-generated default definition.

But you have an interesting point about using a "semi-pure" virtual destructor in a base class to force its derivation. I didn't know that trick and I'm glad I learned it. Thanks.

PS: your right about the compilation error, I didn't try on my compiler, I just got that info from a quick google search and all the links said the same thing so I figured it was true.

>So in my view, I'm still right
...

Righteous indignation is as heavy a cross to bear as defending an invalid thesis.

@Mike
She got you. You should at least admit it.

@Narue
You may be right, but I don't completely agree. One of the benefits of using pure virtual functions is forcing derived classes to implement them. Though it may be legal, in my mind it breaks the semantics of abstract inheritance. If the function may not be implemented in the derived class, it really shouldn't be defined as a pure virtual function. I would favor letting the derived class implicitly call the base class non-pure virtual function when the function isn't defined in the derived class. I tend to think that if you are having trouble thinking of a pure virtual function to put in your abstract base class, then perhaps the base class shouldn't actually be abstract.

<brace for the wrath>

>>She got you. You should at least admit it.
Well I thought I did! If it wasn't clear, let me say it clearly: You are right Narue and I was wrong. Thank you for increasing my understanding of C++ vocabulary and adding this little trick to my bag-a-tricks.

I thought that "In my view, I'm still right" clearly said that, but maybe I still got something to learn about the English language. So, alternatively:
"De mon point de vue, je n'avais pas tord"
"I min egen uppfattning, hade jag rätt"
"Im meine eigene verständigung, hatte ich recht"
"Minun näkökulmastani, en ole väärässä"

PS: who did you think up-voted Narue's post? (rhetorical)

Edited 6 Years Ago by mike_2000_17: n/a

>She got you. You should at least admit it.
There's nothing wrong with a little feisty stubbornness. ;)

>If the function may not be implemented in the derived class,
>it really shouldn't be defined as a pure virtual function.

A pure virtual function must be implemented in the derived class, this is absolute. With destructors the implicit implementation suffices, so while you don't see it in the source, it's still there. I don't know if that alters your opinion of broken semantics or not, but there you go.

>If the function may not be implemented in the derived class,
>it really shouldn't be defined as a pure virtual function.

A pure virtual function must be implemented in the derived class, this is absolute. With destructors the implicit implementation suffices, so while you don't see it in the source, it's still there. I don't know if that alters your opinion of broken semantics or not, but there you go.

Hmmm....the generality of the word 'may' may have caused some confusion here. Let me re-word.

If the function might not be fully implemented in the derived class, it really shouldn't be defined as a pure virtual function.

>If the function might not be fully implemented in the derived class,
>it really shouldn't be defined as a pure virtual function.

How about "if the function is not required to be explicitly implemented by the programmer of the derived class, it really shouldn't be pure virtual"? That seems to be what you're trying to say, and it's a valid opinion on object-oriented design in C++.

Though I like the usual argument against pure virtual destructors: "if a destructor needs to be pure virtual to make the class abstract (ie. there are no other pure virtuals), the class likely shouldn't be abstract in the first place".

This article has been dead for over six months. Start a new discussion instead.