2017-09-15 6 views
1
#include<iostream> 
using namespace std; 

class Mahesh 
{ 

    public: 
     Mahesh(){ 
     cout<<"Base Constructor is called at here"<<endl<<endl; 
     } 
     virtual ~ Mahesh() 
     { 
     cout<<"Base Destructor is called"<<endl<<endl; 
     } 
}; 

class Purnima:public Mahesh 
{ 

    public: 

     Purnima() 
     { 
     cout<<"Derived class constructor"<<endl<<endl; 
     } 
     ~Purnima(){ 
     cout<<"Derived class Destructor"<<endl<<endl; 
     } 
}; 

int main() 
{ 
    Mahesh *m1; 
    Purnima p1; 
    m1=&p1; 

    return 0; 
} 

Ma question est de savoir si je n'écris pas mot-clé virtual devant destructor puis au-dessus du code fonctionne très bien, alors pourquoi destructor virtuelle?mot-clé Omettre virtuel avant destructor fonctionne encore pratiquement

+1

Mieux dupliquer: https://stackoverflow.com/q/461203/501250 – cdhowie

+4

Aucun des doublons n'est approprié. La réponse est que 'virtual' est hérité, que vous le spécifiez à nouveau dans le destructeur dérivé ou non. – EJP

+3

Vous n'invoquez jamais le destructeur de façon polymorphe. Vous testez essentiellement que la destruction d'une classe dérivée appelle à la fois le destructeur parent et le destructeur dérivé. – chris

Répondre

0

Lorsque vous écrivez le code comme celui-ci

int main() 
{ 
    Mahesh *m1; 
    Purnima p1; 
    m1=&p1; 

    return 0; 
} 

Vous obtenez Purnima p1 automatiquement lorsque vous DESTRUCTED obtenez hors de portée .. c'est la raison pour laquelle vous obtenez appel séquence destructor appropriée.

De toute façon vous ne pouvez pas supprimer le m1 sinon c'est un accident. Essayez de l'enfermer à l'intérieur de la lunette pour mieux le comprendre.

int main() 
{ 
    { 
    Mahesh *m1; 
    Purnima p1; 
    m1=&p1; 
    } 
    cout<<"After Scope.."<<endl; 

    return 0; 
} 

"Après la portée" doit être imprimé après l'appel du destructeur.

Donc, en un mot, vous avez besoin virtual lorsqu'ils traitent avec des types dynamiques

+0

J'ai eu une pensée similaire à cela quand je me suis demandé ce qui se passe si vous affectez un unique_ptr pour pointer vers une variable locale. Il s'avère qu'ils ne sont pas complètement idiot-preuve. – Zebrafish

1

Rien dans ce code nécessite un destructeur virtuel, il fait, en effet, beau travail. Vous avez besoin d'un destructeur virtuel si vous supprimez un objet d'un type dérivé via un pointeur vers le type de base. Comme ceci:

Mahesh *m1 = new Purnima; 
delete m1; 

Si le destructeur de Mahesh n'est pas le comportement virtuel, ce code est non défini. Attention: l'une des manifestations les plus insidieuses du comportement indéfini est que le code "fonctionne bien", jusqu'à ce que vous fassiez un léger changement ailleurs, en préparation d'une démo à votre client le plus important, à quel moment il échouera de manière désastreuse.

+0

Vous avez oublié de mentionner que, une fois que le problème devient évident, le temps nécessaire pour trouver la cause est négativement corrélé avec le temps disponible pour le réparer. Moins vous avez de temps, plus vous en avez besoin. :-) – Peter