68

Possible Duplicate:
Destructors for C++ Interface-like classes

Consider a simple example of a C++ abstract class, used to model an interface:

class IAnimal
{
  virtual void walk()=0;
  virtual ~IAnimal(){}
};

Is it better to have the destructor, or not? I don't think the destructor can be pure virtual, at least my tests give linker errors, so should an empty destructor be included?

EDIT: sorry, typo. It's a destructor not a constructor.

Community
  • 1
  • 1
Mr. Boy
  • 60,845
  • 93
  • 320
  • 589

6 Answers6

70

You should always use a virtual destructor with interfaces. Case in point:

IAnimal* animal = new Lion();
delete animal;

Now what destructor is it going to use? Definately not the Lion's destructor because the interface doesn't know about Lion's destructor.

So, have this if your interface has no memory management:

virtual ~IAnimal(){}
Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
wheaties
  • 35,646
  • 15
  • 94
  • 131
  • Note that "if your interface has no memory management" contradicts "always use a virtual destructor" (and the former is correct). – Steve Jessop Sep 02 '10 at 15:38
  • 1
    As chubsdad pointed out: a **protected** non-virtual destructor would be OK too. – ChrisW Sep 02 '10 at 15:39
  • 4
    You can add the pure specifier to an interface's destructor, but the linker will still want an implementation for it like so: `virtual ~IAnimal() = 0 {}`. – AshleysBrain Sep 02 '10 at 15:39
  • 1
    @Steve Jessop - Poor wording on my part but I personally believe interfaces shouldn't have any memory management, otherwise they're just abstract classes. However, since C++ doesn't have a "true" interface declaration, a la Java or C#, I've run into multiple instances where people confuse the two. Hence, I make it a point to say "no memory management" to cover all bases. – wheaties Sep 02 '10 at 15:53
  • Yes, but although the interface doesn't *implement* anything, it could be part of the interface that some memory management scheme is in operation that doesn't allow `delete` to be called on a pointer-to-interface. For example, the interface could be a subset of some larger interface, and the smaller interface is used only by clients which are not responsible for memory management at all: perhaps Observers or Visitors that are passed the object to inspect. In that case you'd go with the protected non-virtual destructor, even on an interface class: destruction just isn't part of the interface. – Steve Jessop Sep 02 '10 at 16:06
  • @SteveJessop: your argument only holds true if the usage of the interface does not support polymorphic deletion (of an interface pointer), as Herb Sutter’s post explains. So it really depends on how the Interface should be used. While in most cases, I’d assume polymorphic deletion is what you want, you are right that this answer isn’t the complete story. – fnl Aug 30 '22 at 17:37
23

Check out this article by Herb Sutter

Especially this part:

For the special case of the destructor only:

Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual.

This assumes that base class is an 'interface' class as it mostly should be.

Chubsdad
  • 24,777
  • 4
  • 73
  • 129
  • 1
    Interestingly the other 3 guidelines in that write-up may seem rather unconventional. Guideline #1: Prefer to make interfaces nonvirtual, using Template Method. Guideline #2: Prefer to make virtual functions private. Guideline #3: Only if derived classes need to invoke the base implementation of a virtual function, make the virtual function protected. – Andrei Pokrovsky May 10 '16 at 02:39
  • Link appears dead or down. – Alex Jan 16 '19 at 13:15
10

This depends on whether you intend to manage the lifetime of objects polymorphically, using pointers to the interface class.

If you do, then the destructor must be virtual, in order to correctly delete the objects. Deleting a base-class pointer that doesn't have a virtual destructor is invalid, and gives undefined behaviour.

If you don't, then you should enforce this by making the destructor non-virtual and protected, so only derived classes can be deleted.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

an empty constructor should probably be included since a typical use of an interface involves putting a pointer to some concrete object in a container, which will otherwise call the wrong destructer and will not clean the memory correctly. so if anyone is going to delete derived objects through a pointer to Ianimal make a virtual destructor, else make your destructor nonvirtual and protected. making your destructor pure virtual is probably not such a good idea, since it forces implementers of derived classes to override your destructor, eventhough they might want to do nothing

flownt
  • 760
  • 5
  • 11
0

I think it should be a pure virtual destructor for interfaces, and all other methods are pure virtual as well.

duffymo
  • 305,152
  • 44
  • 369
  • 561
0

The only reason not to make the destructor virtual would be to save the space needed for the vptr. As you need the vptr anyway because you have another virtual function, I would make the destructor virtual.

gpeche
  • 21,974
  • 5
  • 38
  • 51
  • Should it have a destructor at all though? – Mr. Boy Sep 02 '10 at 15:32
  • 2
    As far as I know every base class has a destructor, either one explicitly defined or automatically created by the compiler. Destructors created by the compiler are non-virtual. – gpeche Sep 02 '10 at 18:39