nitin_cherian
nitin_cherian

Reputation: 6655

Pure virtual destructor definition inside class gives compilation error

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?

Upvotes: 14

Views: 5428

Answers (5)

Adam Zalcman
Adam Zalcman

Reputation: 27233

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.

Upvotes: 5

ronag
ronag

Reputation: 51255

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.

Upvotes: 13

FailedDev
FailedDev

Reputation: 26930

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.
};

Upvotes: 4

xmoex
xmoex

Reputation: 2702

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

Upvotes: 8

Luchian Grigore
Luchian Grigore

Reputation: 258568

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.

Upvotes: 3

Related Questions