3

I would like to define a class that looks like this:

class IHaveVirtualDestructor
{
public:
    virtual ~IHaveVirtualDestructor();
};

And I would like all my interface and abstract classes to inherit this class. Is it a good practice? Or should every interface/abstract class define its own virtual destructor? What are the drawbacks?

Alex Shtoff
  • 2,520
  • 1
  • 25
  • 53
  • Are you asking whether you should define the destructor in the base, or not? In your code sample you only declare it, so it isn't clear what you are asking. – juanchopanza Jul 16 '12 at 11:10
  • No. I am asking weather I should define such a base class and use it for all the interface classes in my project, or just define a virtual destructor where needed. – Alex Shtoff Jul 16 '12 at 11:42

4 Answers4

3

I would like all my interface and abstract classes to inherit this class. Is it a good practice?

It sounds good. The benefits are more like that of noncopyable class.

Any class deriving from them looks like documented just by having a quick glance, otherwise one has to see the declaration of destructor to ensure whether the destructor is virtual or not.

Making the default constructor protected would be a good idea:

class IHaveVirtualDestructor
{
  protected:
     virtual ~IHaveVirtualDestructor() {} //make it protected as well
     IHaveVirtualDestructor() {}
};

A better name is probably needed:

  • AbstractBase
  • PolymorphicObject (taken from @James Kanze's answer)
Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • You also have to define the destructor somehow (just add an empty pair of braces). – Alexandre C. Jul 16 '12 at 11:16
  • @AlexandreC.: Yeah. I thought OP understands that well. (I edited my post anyway). – Nawaz Jul 16 '12 at 11:17
  • 1
    I understand the motivation behind making the constructor and destructor protected, but what harm does it do if someone _does_ create an instance of this class? (The main reason for this use of protected is when you expect people to derive from the class, but you don't want a virtual destructor.) – James Kanze Jul 16 '12 at 11:19
  • @JamesKanze: As you said *"The main reason for this use of protected is when you expect people to derive from the class"*. That answers why I made it `protected`. – Nawaz Jul 16 '12 at 11:21
  • What about instead making the destructor pure virtual with a default implementation? EDIT: Then any IHaveVirtualDestructor could be sent to someone who is responsible for deleting them. – Johan Lundberg Jul 16 '12 at 11:24
  • @JohanLundberg: I don't see any advantage in doing that. – Nawaz Jul 16 '12 at 11:25
  • @Nawez, I ninja-edited my comment so your answer now points to a non-visible comment ;) – Johan Lundberg Jul 16 '12 at 11:27
  • @Nawaz You didn't read the complete phrase: "_but_ do not what to provide a virtual destructor". I was thinking about cases like `std::iterator`. (Which doesn't make the destructor protected because, at least pre-C++11, doing so would have meant that it was non-trivial.) – James Kanze Jul 16 '12 at 11:39
  • @JamesKanze: The whole purpose of this class it to have `virtual` destructor for this, as well as for all derived classes. So I don't understand why you said *"but you don't want a virtual destructor"* – Nawaz Jul 16 '12 at 12:18
  • @Nawaz Because that's the usual reason for making the destructor protected. I was questioning the utility of your making the members protected, given that the usual motivation is absent. – James Kanze Jul 16 '12 at 12:38
  • @JamesKanze: The question is all about having a `virtual` destructor in the base class (which is why the class is so named). I don't see why would anyone assume anything else. – Nawaz Jul 16 '12 at 12:42
  • @Nawaz Which is why I asked the question to begin with. Why the protected members, since the question presented a case where they aren't normally used. – James Kanze Jul 16 '12 at 13:14
  • @JamesKanze: But that is pretty much clear in this context, isn't? – Nawaz Jul 16 '12 at 13:16
3

I'm not sure it's worth the effort, but if I were to do it, I'd give the class a name which expresses its purpose, not its implementation. Something like Interface or PolymorphicObject.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
3

It depends on whether you think it's harder to forget to add a virtual destructor to a class or to add IHaveVirtualDestructor as a base class.

If I where afraid of such errors, I would tend to use a static code analyzer.

And think about the reader of the class. The IHaveVirtualDestructor have to be looked up. Seeing a virtual, inlined and empty destructor is much more idiomatic.

Kind regards Torsten

Torsten Robitzki
  • 3,041
  • 1
  • 21
  • 35
0

All subclasses will have implicit virtual distructor if base class distructor is defined virtual. It will be even better if you define distructor as pure virtual if its purpose is to make compulsion to subclasses define virtual distructor,

Sach
  • 659
  • 8
  • 20
  • The whole purpose is preventing memory leaks. And I don't see any point in making the derived classes define their own virtual destructor over and over again. – Alex Shtoff Jul 16 '12 at 11:13
  • 2
    @Alex I don't see what this has to do with memory leaks. It's more a question of undefined behavior---if you delete through a pointer to the base class, and the destructor is not virtual, you have undefined behavior. – James Kanze Jul 16 '12 at 11:17
  • @JamesKanze: memory leak can be one of the possible consequences of UB, no? – Nawaz Jul 16 '12 at 11:23
  • Agree with @JamesKanze. Alex: if you are making base class distructor as virtual and you are deleting object using base class pointer, it will always going to distruct correct object. there wont be memory leak in that case. – Sach Jul 16 '12 at 11:23
  • I want the *correct* destructor to be called when deleting objects via pointers, otherwise we will have memory leaks because some resources will not be deallocated. This is what the virtual destructor is for. – Alex Shtoff Jul 16 '12 at 11:39
  • @Nawaz Anything can be a consequence of UB. – James Kanze Jul 16 '12 at 11:44
  • @Alex If you delete through a pointer to the base class, and the destructor isn't virtual, you will have undefined behavior. It _might_ call the incorrect constructor, but it's just as likely that after that, it calls `operator new` with the wrong address, or calls the wrong `operator new`. – James Kanze Jul 16 '12 at 11:47