13

The pure virtual destructor in base class should have a definition. Otherwise compiler will generate a call to base class destructor from the derived class destructor during link-time and will cause a link-error.

I tried to define the pure virtual destructor inside the base class like below:

class base
{
   public:
      base()
      {
         cout << "constructor in base class\n";
      }

      virtual ~base()=0
      {}
};

This gave the compilation error:

error: pure-specifier on function-definition

Then i tried to define the function outside the base class like below:

class base
{
   public:
      base()
      {
         cout << "constructor in base class\n";
      }

      virtual ~base()=0;
};

base::~base()
{

}

This removes the compilation error and it behaves as my understanding.

But my question is how does defining the pure virtual destructor outside the base class removes the compilation error?

nitin_cherian
  • 6,405
  • 21
  • 76
  • 127
  • a pure virtual member function or destructor cannot have any body (but ` =0` instead). – Basile Starynkevitch Nov 19 '11 at 14:18
  • There is an exception for `pure virtual destructor`. It should have a definition, otherwise will cause link-error, when the derived class destructor invokes the base class destructor. – nitin_cherian Nov 19 '11 at 14:19
  • I'm assuming the only reason to declare a pure virtual destructor whose implementation is empty is if it the pure virtual destructor was needed to make the class abstract. Otherwise, you should simply declare the destructor virtual. Is this true? – Lou Oct 02 '14 at 22:27

5 Answers5

12

Your second example is correct.

A lot of the other answers assume that it is illegal to have a pure virtual function with a default implementation, however that is incorrect.

In the case of a pure virtual destructor you must have a definition (see the link in xmoex answer).

It is true that:

§10.4/2 a function declaration cannot provide both a pure-specifier and a definition

However, as you noticed it possible to provide a definition outside of the declaration.

ronag
  • 49,529
  • 25
  • 126
  • 221
7

i looked at this page:

http://www.gotw.ca/gotw/031.htm

and from my understanding a pure virtual destructor must have a definition (even an empty one) as every derived class has to call the base classes destructor

xmoex
  • 2,602
  • 22
  • 36
  • 1
    Why was `xmoex` answer given a down vote. He not only gave a good link to go through but also threw more light for the question. Sad! – nitin_cherian Nov 19 '11 at 14:26
5

It is invalid syntax to write:

virtual ~base()=0
{}

If you want to supply implementation of a pure virtual member function, you should do it outside of the class. Most of the time you should not do this, since pure virtual functions should never be called anyhow. It is however possible to define implementation for pure virtual functions.

In fact, a pure virtual destructor must have an implementation. This is because destructors of all base classes are called on object destruction regardless of whether destructor in a given class is pure virtual or not.

Thus, if you create an instance of any of the classes derived from base then at some point destructors of all classes to which the object belongs will be called including the base::~base() destructor. If you do not define it, the linker will not find a required symbol and will complain.

Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
3

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. So in contrast to @Kiril's answer I would say that pure virtual functions can have implementations.

Somewhat off topic :

struct base {
    virtual void func() = 0;
};

void base::func() { /* default implementation */ }

class derived : public base{
    void func() { base::func(); } // have to explicitly call default implementation.
};
FailedDev
  • 26,680
  • 9
  • 53
  • 73
2

Pure virtual methods can have implementations, but they make the base class abstract and force deriving classes to overwrite those methods.

Say you have a pointer member in the base class. You want to delete it on the destructor but also make the class abstract - so you implement to pure virtual destructor.

This is an implementation detail - the fact that the destructor is implemented should't be visible from the outside.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625