2010-06-24 8 views
-1
class A { 
public: 
    A() { } 
    ~A() { cout << "A Destructor \n" ; } 
}; 

class B :public A{ 
    public: 
    B() { } 
    virtual ~B() { cout << "B Destructor \n" ; } 
}; 

class C : public B { 
    public: 
    C() { } 
    ~C() { cout << "C Destructor \n"; } 
}; 

int main() 
{ 

    A *pointA = new A; 
    A *pointB = new B; 
    A *pointC = new C; 

    delete pointA; 
    delete pointB; 
    delete pointC; 
} 
+4

Est-ce ce devoir? – Patrick

+0

Je suis d'accord avec Patrick, ça sent les devoirs. – Puppy

+0

Ce ne sont pas les devoirs. J'essaie de comprendre, pourquoi il lance un comportement indéfini? – user373215

Répondre

10

Il invoquera un comportement non défini lors de la deuxième (et troisième) suppression, car le destructeur de A n'est pas virtuel.

§5.3.5/3:

si le type statique de l'opérande est différent de son type dynamique, le type statique est une classe de base de type dynamique de l'opérande et le type statique doit avoir un destructeur virtuel ou le comportement est indéfini.


Si vous faites le destructor d'un comportement virtuel, vous obtenez bien défini, et la destructor du type dynamique est appelée. (Et chacun de ceux appelle à son tour la destructor de base.) Votre sortie serait:

A destructor
B destructor
A destructor
C destructor
B destructor
A destructor


Pour ce que ça vaut, quand vous êtes si près d'un extrait compilable, vous devriez laisser t il inclut. En outre, il suffit d'utiliser struct au lieu de class pour être concis sur les choses public, et laisser de côté les constructeurs vides.

+0

Merci beaucoup Gman. – user373215

0

Comme GMan l'a souligné, tenter d'appeler l'opérateur delete sur un pointeur de base nécessite un destructeur virtuel pour que le compilateur puisse détruire correctement les objets de la sous-classe. Beaucoup de gens simplifient cela à une règle comme, "Si une classe a des fonctions virtuelles, elle a besoin d'un destructeur virtuel." Ce n'est pas nécessairement le cas; Même une classe de base qui n'a pas de fonctions virtuelles a toujours besoin d'un destructeur virtuel si vous voulez permettre aux clients de supprimer la classe via un pointeur de base. Si vous ne le faites pas, le destructeur devrait être protégé et non public.

Il y a un excellent livre qui décrit ceci en détail et plus appelé C++ Coding Standards par Herb Sutter. Je le recommande comme point de départ dans vos aventures en C++. :-)

Questions connexes