views:

1277

answers:

5

Hi,

I have a solid understanding of most OO theory but the one thing that confuses me a lot is virtual destructors.

I thought that the destructor always gets called no matter what and for every object in the chain.

When are you meant to make them virtual and why?

+2  A: 

Make the destructor virtual whenever your class is polymorphic.

yesraaj
+4  A: 

See this: Virtual Destructor

Naveen
+29  A: 

Virtual destructors are useful when you can manipulate an instance of a derived class through a pointer to base class:

class Base 
{
    // some virtual methods
};

class Derived : public Base
{
    ~Derived()
    {
        // Do some important cleanup
    }
}

Here, you'll notice that I didn't declare Base's destructor to be virtual. Now, let's have a look at the following snippet:

Base *b = new Derived();
// use b
delete b; // Here's the problem! Since Base's destructor is not virtual,
          // it's ~Base that is called and not ~Derived. Therefore, all the important
          // cleanup is not performed, which can create several resource leaks

To sum up, always make base classes' destructors virtual when they're meant to be manipulated polymorphically.

If you want to prevent the deletion of an instance through a base class pointer, you can make the base class destuctor protected and nonvirtual; by doing so, the compiler won't let you call delete on a base class pointer.

You can learn more about virtuality and virtual base class destructor in this article from Herb Sutter.

Luc Touraille
This would explain why i had massive leaks using a factory i made before. All makes sense now. Thanks
Lodle
Worth adding that to prevent deletion through a base class interface, make the destructor protected and non-virtual.
workmad3
That was the exception I was talking about, but you're right, it's worth mentioning.
Luc Touraille
Would this also work if the pointer was a void*?
Lodle
No, it wouldn't. Void pointers don't know about destructors.
Leon Timmermans
No, it wouldn't work with a void*. The compiler knows nothing about what a void * points at. All it knows is that it's a memory location. You need to cast the pointer to a type to tell the compiler what's there.
Rob K
I wish I could up vote a comment. workmad3, that is an amazing insight. I knew there were exceptions to virtual base class destructor rule but making it protected enforces correct use, possible avoiding future errors. thanks for the insight.
caspin
+5  A: 

Declare destructors virtual in polymorphic base classes. This is Item 7 in Scott Meyers' Effective C++. Meyers goes on to summarize that if a class has any virtual function, it should have a virtual destructor, and that classes not designed to be base classes or not designed to be used polymorphically should not declare virtual destructors.

Bill the Lizard
A: 

Also be aware that deleting a base class pointer when there is no virtual destructor will result in undefined behavior. Something that I learned just recently:

http://stackoverflow.com/questions/408196/how-should-overriding-delete-in-c-behave

I've been using C++ for years and I still manage to hang myself.

BigSandwich