Destructeur virtuel en C++

Destructeur Virtuel En C



C ++ est le langage utilisé pour donner une base au concept de base de la programmation et renforce la pensée logique des programmeurs. En C++, la POO joue un rôle essentiel car la POO est un langage orienté objet qui crée les objets des classes. En POO, on étudie les classes et les objets. Les classes contiennent les membres de données qui sont des variables de différents types et différentes fonctions membres. Avec l'aide d'instances, nous accédons aux données de n'importe quelle classe. Chaque classe a son constructeur et son destructeur lorsque vous créez la classe. Le constructeur est appelé lui-même lorsque l'objet de cette classe est créé. Nous pouvons également initialiser les variables d'une classe à l'intérieur du constructeur. Les destructeurs sont également créés automatiquement avec le constructeur mais les destructeurs détruisent l'objet et c'est la dernière fonction qui est appelée avant de détruire l'objet. Le nom de la classe, par exemple la classe « Profession », est créé. Son constructeur est Profession() et le destructeur est ~Profession(). Les trois portent le même nom.

Après avoir parlé de la POO, des constructeurs et des destructeurs, parlons maintenant des destructeurs virtuels. Les destructeurs virtuels, comme leur nom l'indique, détruisent l'objet. Nous avons une classe de base et une classe dérivée dérivée de la classe de base. Les deux classes ont leurs constructeurs et leurs destructeurs. Le destructeur virtuel libère la mémoire qui est attribuée via l'objet de la classe dérivée tout en supprimant les objets de la classe dérivée à l'aide d'un pointeur de classe de base avec le mot-clé 'virtual'.

Pourquoi utilisons-nous le destructeur virtuel ?

Lorsque l'exécution des fonctions membres de la classe est terminée ou que l'exécution de la méthode main() est sur le point de se terminer, le destructeur est automatiquement appelé pour libérer la mémoire allouée lors de la création de l'objet. Maintenant, pourquoi utilisons-nous un destructeur virtuel ? Lorsque la classe de base est supprimée qui pointe vers la classe dérivée, le pointeur (*) est utilisé ici. Le destructeur de classe de base n'est appelé que pendant ce processus. Le destructeur de classe dérivé n'est pas appelé, ce qui entraîne des problèmes. L'un d'eux est un problème de fuite de mémoire. Pour éviter ce problème et sécuriser notre code, nous détruisons virtuellement les objets pour libérer l'espace mémoire qui était alloué lors de la création des objets en supprimant le destructeur de classe de base.

Exemple de base C++ sans destructeur virtuel

Voyons comment le programme fonctionne sans destructeur virtuel avec un programme simple qui supprime le pointeur.

Code:

#include

en utilisant l'espace de noms std ;
classe Parent_Class0
{
Publique :
Parent_Class0 ( )
{ cout << 'Constructeur de classe parent' << fin ; }
~Parent_Class0 ( )
{ cout << 'Destructeur de classe parent' << fin ; }
} ;
classe Enfant_1 : public Parent_Class0
{
Publique :
Enfant_1 ( )
{ cout << 'Constructeur de classe enfant' << fin ; }
~Enfant_1 ( )
{ cout << 'Destructeur de classe enfant' << fin ; }
} ;
entier principale ( )
{
Parent_Class0 * aiguille = nouvel enfant_1 ( ) ;
supprimer le pointeur ;
retour 0 ;
}

Ce code explique comment le code s'exécute sans destructeur virtuel. Tout d'abord, créez une classe nommée 'Parent_Class0' qui sera la classe parent. Dans cette classe, créez un constructeur et un destructeur. Comme nous le savons, le constructeur et le destructeur portent le même nom que la classe. Le destructeur est représenté de la même manière que le constructeur mais il a un symbole (~) qui le différencie du constructeur. À l'intérieur du constructeur et du destructeur, imprimez un message en utilisant 'cout<<'. Maintenant, créez une autre classe qui est 'Child_1'. Cette classe est dérivée de la classe parent, 'Parent_Class0'. La classe dérivée a son constructeur et son destructeur qui contiennent un message à imprimer sur l'écran de sortie.

Dans la méthode main(), nous créons une instance de « Parent_Class0 » et lui attribuons une classe dérivée. Le point crucial à retenir dans ce cas est que nous utilisons un pointeur pour récupérer la classe parent. Lorsqu'il entre dans la classe parent, il exécute le constructeur de la classe parent. Ensuite, il va à la classe enfant et exécute son constructeur. Avant d'exécuter le destructeur de la classe enfant, il doit exécuter le destructeur de la classe parent. Le compilateur exécute le destructeur de la classe parent et termine la classe sans exécuter le destructeur d'une classe enfant. C'est le problème; il ne libère pas la mémoire de la classe de l'enfant. Il représente le constructeur d'une classe parent, le constructeur d'une classe enfant et le destructeur d'une classe parent. Cela montre que le destructeur d'une classe enfant n'est pas exécuté. Après cette exécution, nous supprimons le pointeur dans la fonction main().

Production:

Exemple C++ avec destructeur virtuel

Discutons du destructeur virtuel avec un code simple pour différencier son fonctionnement avec et sans destructeur virtuel.

Code:

#include

en utilisant l'espace de noms std ;
classe Parent_Class0
{
Publique :
Parent_Class0 ( )
{ cout << 'Constructeur de classe parent' << fin ; }
virtuelle ~ Parent_Class0 ( )
{ cout << 'Destructeur de classe parent' << fin ; }
} ;
classe Enfant_1 : public Parent_Class0
{
Publique :
Enfant_1 ( )
{ cout << 'Constructeur de classe enfant' << fin ; }
virtuel ~Child_1 ( )
{ cout << 'Destructeur de classe enfant' << fin ; }
} ;
entier principale ( )
{
Parent_Class0 * aiguille = nouvel enfant_1 ( ) ;
supprimer le pointeur ;
retour 0 ;
}

Le premier programme a expliqué le problème auquel nous sommes confrontés sans destructeur virtuel. Maintenant, ce code résoudra ce problème en utilisant un destructeur virtuel. Tout d'abord, copiez le premier code et ajoutez simplement un mot-clé à deux endroits dans ce programme. Ce mot est « virtuel ». Insérez ce mot avec le destructeur de la classe parent, 'Parent_Class0'. De même, mentionnez ceci avec le destructeur de la classe enfant qui est 'Child_1' qui est dérivé de la classe parent. Ce mot-clé 'virtuel' apporte un petit changement et il exécute d'abord le destructeur de la classe enfant 'Child_1'. Ensuite, il exécute le destructeur de la classe parent, 'Parent_Class0'. Le reste du programme fonctionne de la même manière car il fonctionne sans destructeur virtuel. En ajoutant ce petit morceau de code, nous pouvons sauver notre mémoire des fuites. Maintenant, il affiche quatre messages sur la console. D'abord, le constructeur d'une classe parent, puis le constructeur d'une classe enfant, le destructeur d'une classe enfant et le destructeur d'une classe parent. À la fin, nous supprimons le pointeur dans la méthode main().

Production:

Exemple C++ de destructeur virtuel pur

Dans ce code, nous parlerons du destructeur virtuel pur, de son fonctionnement et de sa différence avec un destructeur virtuel.

Code:

#include

classe Parent_0 {
Publique :
virtuel ~Parent_0 ( ) = 0 ;
} ;
Parent_0 :: ~Parent_0 ( )
{
std :: cout << 'Bonjour, je suis Pure Destructor. Vous m'avez appelé!' ;
}
classe Enfant_0 : public Parent_0 {
Publique :
~Enfant_0 ( ) { std :: cout << 'Le destructeur dérivé est ici \n ' ; }
} ;

entier principale ( )
{
Parent_0 * ptr_0 = nouvel enfant_0 ( ) ;
supprimer ptr_0 ;
retour 0 ;
}

La classe parent 'Parent_0' est créée dans la première étape du code. À l'intérieur, créez le destructeur parent virtuel et attribuez-lui la valeur 0. Cela définit le destructeur virtuel sur un destructeur virtuel pur, ce qui signifie que la classe parent est maintenant abstraite et que nous ne pouvons pas créer les instances de cette classe. En dehors de la classe parent 'Parent_0', définissez les destructeurs et std::cout. Le texte requis est affiché en utilisant le std :: cout. Ensuite, dérivez une classe 'Child_0' de la classe parent et définissez son destructeur. À l'intérieur du destructeur, imprimez un message. Dans la fonction main(), créez le pointeur de la classe parent et affectez-lui la classe enfant.

Le compilateur va à la classe parent 'Parent_0'. Lorsque le pointeur est créé, son constructeur est automatiquement appelé. Ensuite, le compilateur va dans la classe enfant pour invoquer son constructeur. Après l'exécution réussie du constructeur, il exécute le destructeur d'une classe enfant 'Child_0'. Ensuite, il exécute le destructeur d'une classe parent. De cette façon, nous pouvons créer un destructeur virtuel pur. Il n'est pas encouragé de l'utiliser car en employant cette méthode, la classe parent devient abstraite ce qui la rend inutile. La méthodologie la plus utilisée est celle du destructeur virtuel et c'est une bonne pratique.

Production:

Conclusion

Nous avons appris le destructeur virtuel en partant du concept de POO pour nous diriger vers les constructeurs et les destructeurs. Après avoir expliqué tout cela, nous avons discuté en détail du destructeur virtuel avec des exemples de codage et un destructeur virtuel pur. Avant d'expliquer le destructeur virtuel, nous devons connaître les constructeurs, les destructeurs et l'héritage. En héritage, on hérite des classes d'une classe mère. Les classes enfant peuvent être plusieurs mais la classe parent n'en est qu'une. Les destructeurs virtuels et les destructeurs virtuels purs sont appliqués en héritage pour éviter les fuites de mémoire. De l'exemple de base à l'exemple avancé, nous avons couvert tout ce que vous devez savoir pour commencer à utiliser et détruire virtuellement la mémoire de la classe dérivée.