views:

113

answers:

3

I have

struct IMyInterface
{
   virtual method1() = 0;
   virtual method2() = 0;
};

GCC insists that I have

struct IMyInterface
{
   virtual method1() = 0;
   virtual method2() = 0;
   virtual ~IMyInterface(){};
};

I dont see why. A pure interface is all about the interface (duh). The destructor is part of the internal implementation details of a concrete implementer of the interface; it does not form part of the interface. I understand the whole slicing issue (or at least I think I do)

So my question is - is GCC right to insist on it and if so why?

+8  A: 

According to the C++ spec, yes.

You need to declare the destructor virtual because otherwise, later

    IMyInterface * ptr = getARealOne();
    delete ptr;

won't call the destructor on the derived class (because the destructor isn't in the VTable)

It needs to be non-pure because base class destructors are always called by the sub-class destructor.

To further explain, C++ doesn't have a concept of an interface in the same way that Java or C# do. It's just a convention to use only pure-virtual methods, and think of that as an interface. The other rules about C++ destructors make it need to be non-pure, which breaks the similarity to interfaces in other languages, but those languages didn't exist at the time these rules were made.

Lou Franco
Nitpick - I think you can make it pure virtual if you want to require child classes to implement it. But you still have to provide an implementation for the reasons you stated.
Kristo
I don't think so -- it will be called, so it better have a definition. I haven't tried it, but usually a pure-virtual is implemented by the compiler as putting an error function in the VTable to complain that it was called. Perhaps I could imagine a special case for destructors, but I'm pretty sure that that isn't what the spec says (Not 100% though)
Lou Franco
@Lou Franco: Pure virtual functions can have definitions.
Billy ONeal
@Lou: "pure" doesn't mean that it doesn't have a definition, just that it must be overridden. The destructor can be pure or not, but must have a definition.
Mike Seymour
Yes -- sorry, that's right. Not the way he's doing it (at the point of declaration).
Lou Franco
Here's the relevant part of the spec discussion http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#230
Lou Franco
You are right. i keep expecting c++ to behave like c# :(
pm100
+2  A: 

If you don't declare the virtual d'tor in the base class, deleting objects of derived classes through a pointer to the base class leads to the wrong destructor being called, and thus to undefined behaviour and resource leaking.

struct A {

  virtual ~A() {}

};

struct B : A {

   std::string us_constitution;  
};


B* pb = new B();
A* pa = pb;

delete pa; // without the virtual d'tor in the base class, 'B::us_constitution' would never be freed.
Alexander Gessler
Nitpick: B::us_constitution cannot be free'd because it was never new'd. The storage it uses, however, will not be returned to the system without the virtual destructor.
Billy ONeal
A: 

The code you specified there is not a destructor. A destructor would be something "virtual ~IMyInterface();".

JMcCarty
This really belongs in a comment but I won't downvote because you don't have enough rep to comment.
Billy ONeal