The question arose about the virtual destructor.
As far as I understood – the virtual destructor is needed that in the inherited class, which we have (from the base) can be called (straight from there) the basic destructor, and that A simple destructor inherited class does not understand, then you need to create a virtual one.
And all this so that there is no memory leakage.
So I understood the essence?
Answer 1, Authority 100%
Not, little wrong. The basic class destructor from the destructor of the derivative is not necessary (and it is impossible), it will turn out automatically. The problem is different: the destructor Derivative class may not be called!
Imagine this situation:
class person
{
~ Person () {} // destructor is not virtual
};
Class Spy: Public Person
{
Gadget * Gadgets;
Public:
SPY () {Gadgets = New Gadget [10]; }
~ Spy () {delete [] gadgets; }
};
STD :: Vector & LT; Person * & gt; Citizens;
// Fill the values
For (Person * Citizen: Citizens)
Delete Citizen;
What happens if the list is one Spy
? But what: when destroying an object of type Spy
on the Person *
indicator, will call the ~ Person
. So, the memory for an array of Gadgets
will not be released. Here you have a memory leak.
In fact, in addition to the memory leakage, any other trouble may occur, because the destructor for which you expected will not call! For example, a file may not close, and at the next attempt to open the program to depart. Or the mutex will not let go, and when trying to get the program hangs. Well, a lot of all sorts of disasters can occur.
Worse, according to the standard lack of a virtual destructor in this case is undefined Behaviour, that is, the program has the right to do anything: format the hard drive, confess to love for your chemistry through VKontakte or pour Valerian to a bowl of Wischas.
Yes, and in C destructors there is no.
Answer 2, Authority 31%
Add to a very good explanation of the user vladd The following code that can be found everywhere:
# include & lt; iostream & gt;
Class Base.
{
Public:
Base () {STD :: COUT & LT; & LT; "Base Constructor \ N" & lt; & lt; STD :: ENDL; }
Virtual ~ Base () {STD :: COUT & LT; & LT; "BASE DESTRUCTOR \ N" & lt; & lt; STD :: ENDL; }
};
Class DERIVE: Public Base
{
Public:
DERIVE () {STD :: COUT & LT; & LT; "DERIVE CONTRUCTOR \ N" & LT; & LT; STD :: ENDL; }
Virtual ~ DERIVE () {STD :: COUT & LT; & LT; "DERIVE DESTRUCTOR \ N" & lt; & lt; STD :: ENDL; }
};
INT MAIN ()
{
Base * PTR = new DERIVE;
Delete PTR;
Return 0;
}
The result will be:
$ ./example
Base Constructor.
DERIVE CONTERCOR.
DERIVE DESTRUCTOR.
Base Destructor
Pay attention to the order of calls of designers and destructors. Destructors are called in reverse order regarding constructor calls. And now remove the Virtual keyword
from ~ base ()
and ~ derive ()
, as a result of the destructor of class DERIVE
will not be called:
$ ./example
Base Constructor.
DERIVE CONTERCOR.
Base Destructor
If your base class is planned to continue to inherit another cool destructor should be virtual. I recommend to read Meyers cattle, he has excellent books on C++.