1

During my design sometimes I have the situation that I add / or remove virtual methods. The rule of thumb I know is, that I shall have a virtual destructor once I have virtual methods.

My question: Is there any harm if I do add a virtual destructor straight away when I create the class (so even with no virtual methods yet)? Basically the idea is not to forget it later. Especially with n derived classes I would not need to change it in n places later.

Horst Walter
  • 13,663
  • 32
  • 126
  • 228

5 Answers5

5

There's a tiny overhead in the size of the virtual function table. Probably not worth worrying about. A virtual destructor will also make your class a non-aggregate, a non-trivial class, a non-standard-layout class, and therefore also a non-POD class. This may be undesirable, depending on the problem at hand.

However, I recommend specifically designing your classes to be either polymorphic or not. If they're going to be used polymorphically, give them a virtual destructor. If not, don't. If you ever need to change it, do it when you need it.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • 3
    I am surprised everyone here talks of virtual table overhead which is marginal but not the fact that presence of `virtual` destructor makes the class a non POD class which may not be desired. Reminds me of a [similar question](http://stackoverflow.com/a/8298219/452307) I answered some time ago – Alok Save Mar 24 '13 at 11:45
  • @AlokSave it also makes it non-aggregate, which could be an issue. – juanchopanza Mar 24 '13 at 12:13
  • @juanchopanza Added that too. Thanks to both of you. – Joseph Mansfield Mar 24 '13 at 12:15
1

The only harm is that your class and all derived classes will have a v-table which is a marginal increase in size. You wouldn't need to make any changes whatsoever in your derived classes even if you decide to make the base class destructor virtual later on. For any method including the destructor, you need to use the virtual key word only once - in the base class. The same method in the derived class automatically becomes virtual.

As an alternative, you can make your destructor protected. This will prevent accidental call of delete using a base class pointer.

class A
{
    protected:
    ~A(){}
};

class B : public A
{};

int main(int argc, char *argv[])
{
    A * p = new B;
    delete p;
}

On my compiler, it gives the following error

error C2248: 'A::~A' : cannot access protected member declared in class 'A' a.cpp(9) : compiler has generated 'A::~A' here a.cpp(6) : see declaration of 'A'

user93353
  • 13,733
  • 8
  • 60
  • 122
1

No, it makes perfectly sense to have a virtual destructor, even if you don't have any other virtual methods.

However, if memory usage is important, every byte counts and you can gain 4 or 8 bytes if you don't have any virtual methods. In my application I have some classes of which I have millions of instances. In that case, getting rid of a v-pointer in your class really makes sense.

I don't completely follow why you need to change your derived classes if you change the destructor from non-virtual to virtual (or vice versa). Once a method is virtual, the same method will be virtual in all derived classes, even if you don't specify virtual. Nevertheless, because of style reasons, it may be advised to add virtual in derived classes, even if it is not needed.

Patrick
  • 23,217
  • 12
  • 67
  • 130
1

Don't blindly follow rules. That is, follow rules, but don't do it blindly.

The only case when a virtual destructor is truly necessary is when an object is deleted through its base object pointer. The rule of thumb generalizes and simplifies this condition: if an object could possibly be deleted through its base object pointer, then it will be used polymorphically; a polymorphic object is likely to have virtual functions, and an object having virtual functions is likely to bee used polymorphically; therefore, an object with virtual functions is likely to need a virtual destructor.

This is all fine and dandy, the rule mostly works, but there is more important and more fundamental fact that is rarely mentioned, partly because such rules do indeed work. The fact is, there are value-like objects and there are objects of the other kind, which does not have a good name, but I will call them entity-like objects. Entity-like objects have identity separate from their value, they use reference semantics, they should not be copied without good reasons (such as creating a separate identity), they are likely to be accessed polymorphically, etc. Value-like objects have no identity besides their value, they can be copied freely, they should not be used polymorphically, etc. They are so different it would be worth to have different keywords for their classes! When you design your class, you have to decide to which category it belongs. Then your question resolves itself. Entities get virtual destructors, values don't.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

The only reason for having a virtual destructor is so that objects of derived types can be deleted through pointers to the base type. If that's what the class's design calls for, then it must have a virtual destructor, even if it doesn't have any other virtual functions. If the design does not include deleting through a pointer to base then it does not need a virtual destructor, even if it has virtual functions. The belt-and-suspenders folks will tell you to make the destructor virtual anyway, because it doesn't hurt anything, and, well, you just never know. That's not a technical reason; it's a policy choice to protect against users who don't read and follow documentation.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165