destructeur virtuel
En C++, le constructeur ne peut pas être défini comme un constructeur fictif, car le constructeur est appelé uniquement lorsqu'un objet est instancié, et l'implémentation de la fonction virtuelle est en fait appelée via un pointeur de table de fonctions virtuelles, et il n'y a pas de mise à jour de l'objet. Bien sûr, il ne peut pas être appelé sans espace mémoire, donc le constructeur fictif avant d'instancier un objet n'a aucun sens et ne peut pas être implémenté.
Cependant, les destructeurs peuvent être des fonctions virtuelles, et la plupart du temps ils sont déclarés comme destructeurs virtuels. De cette façon, lorsque l'objet de la classe dérivée pointé par le pointeur de classe de base est libéré, le destructeur de la sous-classe peut être compilé dynamiquement et appelé en fonction du type d'objet réel pointé, afin d'obtenir la libération correcte de la mémoire de l'objet. .
Faisons une expérience ci-dessous, veuillez regarder le code :
/************************************//Des : Démo du tutoriel C++//Auteur : Huang/ /Droit d'auteur : www.dotcpp.com//Date : 2017/12/27********************************* * *******/#include<iostream>usingnamespacestd;classPoint{private:intx,y;int*str;public:Point(intx=0,inty=0){this->x=x;this- > y=y;str=newint[100];}~Point(){delete[]str;cout<<CalledPoint'sDestructorandDeletedstr!<<endl;}};classCircle:publicPoint{private:intr;int*str;public : Circle(intx,inty,intR):Point(x,y){r=R;str=newint[100];}~Circle(){delete[]str;cout<<CalledCircle'sDestructorandDeletedstr!<<endl; } };intmain(){Point*p;p=newCircle(10,10,20);deletep;return0;}
Vous pouvez voir le code. Il n'y a pas de destructeur déclaré avec virtual dans la classe de base, et la classe de base et la classe dérivée ont une allocation de mémoire dynamique. Ensuite, nous créons une classe Circle dans la fonction principale en allouant dynamiquement de la mémoire, puis nous la supprimons. La capture d'écran après l'exécution est la suivante :
On voit clairement que seul le destructeur de la classe de base est appelé, de sorte que les 4*100 octets de nouvelle mémoire dans la classe dérivée resteront, provoquant une fuite de mémoire !
Et si le destructeur de la classe de base est déclaré virtuel, le résultat sera bien différent ! A ce moment, l'effet polymorphe apparaît. Il va d'abord libérer l'espace de la classe dérivée, puis libérer l'espace mémoire de la classe de base. Cela se termine parfaitement, comme indiqué ci-dessous :
Ci-dessus, ce sont les avantages apportés par le destructeur virtuel, vous pouvez en faire l'expérience vous-même.