views:

3557

answers:

5

I understand the need for a virtual destructor. But why do we need a pure virtual destructor? In one of the C++ articles, the author has mentioned that we use pure virtual destructor when we want to make a class abstract.

But we can make a class abstract by making any of the member functions as pure virtual.

So my questions are

  1. When do we really make a destructor pure virtual? Can anybody give a good real time example?

  2. When we are creating abstract classes is it a good practice to make the destructor also pure virtual? If yes..then why?

+1  A: 

1) When you want to require the derived classes to do clean-up. This is rare.

2) No, but you want it to be virtual, though.

Steven Sudit
+6  A: 
  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 in most (all?) cases.

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.

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.

Note: The destructor is the only method that even if it is pure virtual has to have an implementation in order for the class it's defined in to be useful (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.
};
Motti
"yes pure virtual functions can have implementations" Then it's not pure virtual.
GMan
If you want to make a class abstract, wouldn't it be simpler to just make all constructors protected?
bdonlan
@GMan, you're mistaken, being pure virtual means derived classes must override this method, this is orthogonal to having an implementation. Check out my code and comment out `foof::bar` if you want to see for yourself.
Motti
@GMan: the C++ FAQ lite says "Note that it is possible to provide a definition for a pure virtual function, but this usually confuses novices and is best avoided until later." http://www.parashift.com/c++-faq-lite/abcs.html#faq-22.4 Wikipedia (that bastion of correctness) also says likewise. I believe the ISO/IEC standard uses similar terminology (unfortunately my copy is at work at the moment)... I agree that it's confusing, and I generally don't use the term without clarification when I'm providing a definition, especially around newer programmers...
leander
Ah, I totally read that and commented without reading the code. Shame on me :(
GMan
+1  A: 

If you want to create an abstract base class:

  • that can't be instantiated (yep, this is redundant with the term "abstract"!)
  • but needs virtual destructor behavior (you intend to carry around pointers to the ABC rather than pointers to the derived types, and delete through them)
  • but does not need any other virtual dispatch behavior for other methods (maybe there are no other methods? consider a simple protected "resource" container that needs a constructors/destructor/assignment but not much else)

...it's easiest to make the class abstract by making the destructor pure virtual and providing a definition (method body) for it.

For our hypothetical ABC:

You guarantee that it cannot be instantiated (even internal to the class itself, this is why private constructors may not be enough), you get the virtual behavior you want for the destructor, and you do not have to find and tag another method that doesn't need virtual dispatch as "virtual".

leander
+4  A: 
Braden
A: 

Whatever Leander has pointed is appropriate and is almost complete. I would like to elaborate first point that he makes "that can't be instantiated". Instantiated means that you doesnt want any object of that particular class to be created. To understand this, ask yourself that why we would be defining a class when we dont want the object to be create? To answe this i will say that let us have a class that supports mathematical functions. Although these can be made as global functions but wouldnt you be happy that all the mathematical operations are isolated into a single class. Just use classname::function to access a methematics class method. So we dont want an object of maths class to be created to use its functions! However, one should understand this that has nothing to do with memoory leaks and all that stuff as we will never be creating objects of this class.

Correct me if i am right. Abhinav [email protected]

abhinav