why do we have virtual destructors?

Started by
5 comments, last by alnite 21 years, 2 months ago
virtual functions are used to define a unique behavior for each inherited (child) classes, but what about virtual destructors? does it matter on how we uninitialize member data so that the destructor need to be virtual? i still have no clue about it. can somebody please explain it to me? 500
Advertisement
lets say we have a class

class Parent
{
public:
Parent() { MyData = new int[100]; }
~Parent() { delete [] MyData; }

private:
int* MyData;
};

everything works fine, as long as there are no subclasses, but if there were and the destructor is not virtual, it won''t be called.
So that each class can have its own individual destructor.

If you have data that you need to clean up (memory allocated off the heap), the actual destructor varies depending on what all you need to free. You could have a base class that frees up a certain amount of memory, and another class that inherits the base class, but needs to clean up more stuff.
quote:Original post by The Reindeer Effect
So that each class can have its own individual destructor.

So, the dtor for each class is not automatically called?
Let''s say I have the following class hierarchy:

Animal
|
Cat
|
My Cat

When an object of My Cat is uninstantiated, the dtor of My Cat is called. Then, Cat''s dtor is called, and then finally Animal''s dtor. Are you saying that the compiler won''t call Cat''s dtor and Animal''s dtor unless their dtors are virtual?

500

  #include <iostream>using namespace std;class Base {public:  Base() { cout << "Base" << endl; }  ~Base() { cout << "~Base" << endl; }};class Derived: public Base {public:  Derived() { cout << "Derived" << endl; }  ~Derived() { cout << "~Derived" << endl; }};int main(){  cout << "Test 1:" << endl;  Derived* d = new Derived;  delete d;  cout << endl;  cout << "Test 2:" << endl;  Base* b = new Derived;  delete b;  cout << endl;  cout << "Press enter..." << endl;  cin.get();}  
Examine the output of the second test case carefully. Then make the destructors virtual and run it again.
quote:Original post by alnite
When an object of My Cat is uninstantiated, the dtor of My Cat is called. Then, Cat''s dtor is called, and then finally Animal''s dtor. Are you saying that the compiler won''t call Cat''s dtor and Animal''s dtor unless their dtors are virtual?


If you have an Animal* that is pointing to a MyCat object and the Animal class doesn''t have a virtual destructor, the effect of calling delete on that pointer is undefined.

Which means that, when writing their compiler, compiler implementers are allowed to assume that this will never happen, don''t have to check nor special case for it.

So, when you do write something like that, your code is actually falling through the cracks in the compiler. The results might make sense (only call Animal''s destructor), because of the way the code is generated, but there is absolutely no guarantee it will stay the same from one compiler to another, or even from one *build* to another.

For all you know, the behaviour might change with the phase of the moon.

[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Fruny knows his crap, I spend my life trying to pretend to be him.

YOU HAVE BEEN FRUNIFIED!!

This topic is closed to new replies.

Advertisement