Pure virtual destructor definition inside class gives compilation error
Asked Answered
Y

5

14

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?

Yaroslavl answered 19/11, 2011 at 14:11 Comment(3)
a pure virtual member function or destructor cannot have any body (but ` =0` instead).Rees
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.Yaroslavl
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?Sunrise
C
13

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.

Contractive answered 19/11, 2011 at 14:21 Comment(3)
K-ballo: A bit more specific please?Contractive
That reference you added is what I was asking about. +1Goods
@Goods I believe ronag made the reference from C++ standard.Yaroslavl
C
8

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

Castellano answered 19/11, 2011 at 14:20 Comment(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!Yaroslavl
S
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.

Shuman answered 19/11, 2011 at 14:20 Comment(1)
+1 on the reason it must be defined. That was the missing piece for me.Sunrise
C
4

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.
};
Charpoy answered 19/11, 2011 at 14:22 Comment(3)
Any pure virtual method can have an implementation, not just the destructor.Goods
@Goods I didn't say otherwise.Charpoy
@Charpoy : It was not off topic, your answer was valuable :), +1 for the answer and humility too :)Yaroslavl
W
3

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.

Whoredom answered 19/11, 2011 at 14:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.