Destruidor Virtual em C++

Destruidor Virtual Em C



C++ é a linguagem que serve para fundamentar o conceito básico de programação e fortalecer o raciocínio lógico dos programadores. Em C++, OOP desempenha um papel vital, pois OOP é uma linguagem Orientada a Objetos que cria os objetos das classes. Em POO, estudamos as classes e os objetos. As classes contêm os membros de dados que são variáveis ​​de diferentes tipos e diferentes funções de membro. Com a ajuda de instâncias, acessamos os dados de qualquer classe. Cada classe tem seu construtor e destruidor quando você cria a classe. O construtor é chamado a si mesmo quando o objeto dessa classe é criado. Também podemos inicializar as variáveis ​​de uma classe dentro do construtor. Os destruidores também são criados automaticamente com o construtor, mas os destruidores destroem o objeto e é a última função chamada antes de destruir o objeto. O nome da classe, por exemplo, a classe “Profissão”, é criado. Seu construtor é Profession() e o destruidor é ~Profession(). Os três têm o mesmo nome.

Depois de falar sobre OOP, construtores e destruidores, vamos falar sobre destruidores virtuais. Os destruidores virtuais, como o nome especifica, destroem o objeto. Temos uma classe base e uma classe derivada que é derivada da classe base. Ambas as classes têm seus construtores e destruidores. O destruidor virtual libera reminiscências que são alocadas por meio do objeto de classe derivada enquanto exclui os objetos da classe derivada usando um ponteiro de classe base com a palavra-chave “virtual”.

Por que usamos o Virtual Destructor?

Quando a execução das funções do membro da classe é concluída ou a execução do método main() está prestes a terminar, o destruidor é chamado automaticamente para liberar a memória alocada durante a criação do objeto. Agora, por que usamos um destruidor virtual? Quando a classe base que aponta para a classe derivada é excluída, o ponteiro (*) é usado aqui. O destruidor da classe base só é chamado durante esse processo. O destruidor de classe derivada não é chamado, o que leva a problemas. Um deles é um problema de vazamento de memória. Para evitar esse problema e tornar nosso código seguro, destruímos virtualmente os objetos para liberar o espaço de memória alocado durante a criação de objetos excluindo o destruidor de classe base.

Exemplo básico de C++ sem destruidor virtual

Vamos ver como o programa funciona sem um destruidor virtual com um programa simples que apaga o ponteiro.

Código:

#include

usando namespace std ;
classe Parent_Class0
{
público :
Parent_Class0 ( )
{ cout << 'Construtor de classe pai' << fim ; }
~Parent_Class0 ( )
{ cout << 'Destruidor de classe pai' << fim ; }
} ;
classe Criança_1 : public Parent_Class0
{
público :
Criança_1 ( )
{ cout << 'Construtor de Classe Filho' << fim ; }
~Criança_1 ( )
{ cout << 'Destruidor de classe filho' << fim ; }
} ;
int a Principal ( )
{
Parent_Class0 * ponteiro = nova Criança_1 ( ) ;
excluir ponteiro ;
Retorna 0 ;
}

Este código explica como o código é executado sem um destruidor virtual. Primeiro de tudo, crie uma classe chamada “Parent_Class0” que será a classe pai. Dentro dessa classe, crie um construtor e um destruidor. Como sabemos, o construtor e o destruidor têm o mesmo nome da classe. O destruidor é representado de forma semelhante ao construtor, mas possui um símbolo (~) que o diferencia do construtor. Dentro do construtor e do destruidor, imprima uma mensagem usando “cout<<”. Agora, crie outra classe que é “Child_1”. Esta classe é derivada da classe pai, “Parent_Class0”. A classe derivada possui seu construtor e destruidor que contém uma mensagem para imprimir na tela de saída.

No método main(), criamos uma instância de “Parent_Class0” e atribuímos uma classe derivada a ela. O ponto crucial a ser lembrado neste caso é que utilizamos um ponteiro para recuperar a classe pai. Quando ele entra na classe pai, ele executa o construtor da classe pai. Em seguida, ele vai para a classe filha e executa seu construtor. Antes de executar o destruidor da classe filha, ele deve executar o destruidor da classe pai. O compilador executa o destruidor da classe pai e encerra a classe sem executar o destruidor de uma classe filha. Esse é o problema; não liberta a memória da aula da criança. Ele representa o construtor de uma classe pai, o construtor de uma classe filha e o destruidor de uma classe pai. Isso mostra que o destruidor de uma classe filha não é executado. Após esta execução, apagamos o ponteiro na função main().

Saída:

Exemplo C++ com Virtual Destructor

Vamos discutir o destruidor virtual com um código simples para diferenciar como ele funciona com e sem um destruidor virtual.

Código:

#include

usando namespace std ;
classe Parent_Class0
{
público :
Parent_Class0 ( )
{ cout << 'Construtor de classe pai' << fim ; }
virtual ~Parent_Class0 ( )
{ cout << 'Destruidor de classe pai' << fim ; }
} ;
classe Criança_1 : public Parent_Class0
{
público :
Criança_1 ( )
{ cout << 'Construtor de Classe Filho' << fim ; }
virtual ~Criança_1 ( )
{ cout << 'Destruidor de classe filho' << fim ; }
} ;
int a Principal ( )
{
Parent_Class0 * ponteiro = nova Criança_1 ( ) ;
excluir ponteiro ;
Retorna 0 ;
}

O primeiro programa explicou o problema que enfrentamos sem um destruidor virtual. Agora, esse código resolverá esse problema usando um destruidor virtual. Primeiro, copie o primeiro código e apenas adicione uma palavra-chave em dois lugares neste programa. Essa palavra é “virtual”. Insira esta palavra com o destruidor da classe pai, “Parent_Class0”. Da mesma forma, mencione isso com o destruidor da classe filha que é “Child_1” que é derivado da classe pai. Essa palavra-chave “virtual” faz uma pequena alteração e executa primeiro o destruidor da classe filha “Child_1”. Em seguida, executa o destruidor da classe pai, “Parent_Class0”. O restante do programa funciona da mesma forma que sem um destruidor virtual. Ao adicionar este pequeno pedaço de código, podemos evitar que nossa memória vaze. Agora, ele exibe quatro mensagens no console. Primeiro, o construtor de uma classe pai, depois o construtor de uma classe filha, o destruidor de uma classe filha e o destruidor de uma classe pai. No final, excluímos o ponteiro dentro do método main().

Saída:

Exemplo C++ de Destruidor Virtual Puro

Neste código, falaremos sobre o destruidor virtual puro, como ele funciona e como ele é diferente de um destruidor virtual.

Código:

#include

classe Pai_0 {
público :
virtual ~Pai_0 ( ) = 0 ;
} ;
Pai_0 :: ~Pai_0 ( )
{
std :: cout << 'Olá, eu sou o Pure Destructor. Você me ligou!' ;
}
classe Criança_0 : public Parent_0 {
público :
~Criança_0 ( ) { std :: cout << 'Destruidor derivado está aqui \n ' ; }
} ;

int a Principal ( )
{
Pai_0 * ptr_0 = nova Criança_0 ( ) ;
excluir ptr_0 ;
Retorna 0 ;
}

A classe pai “Parent_0” é criada na primeira etapa do código. Dentro dele, crie o destruidor pai virtual e atribua-o com 0. Isso define o destruidor virtual como destruidor virtual puro, o que significa que a classe pai agora é abstrata e não podemos criar as instâncias dessa classe. Fora da classe pai “Parent_0”, defina os destruidores e std::cout. O texto necessário é mostrado utilizando o std::cout. Em seguida, derivar uma classe “Child_0” da classe pai e definir seu destruidor. Dentro do destruidor, imprima uma mensagem. Na função main(), crie o ponteiro da classe pai e atribua a ele a classe filha.

O compilador vai para a classe pai “Parent_0”. Quando o ponteiro é criado, seu construtor é chamado automaticamente. Em seguida, o compilador vai para a classe filha para invocar seu construtor. Após a execução bem-sucedida do construtor, ele executa o destruidor de uma classe filha “Child_0”. Em seguida, ele executa o destruidor de uma classe pai. Desta forma, podemos fazer um destruidor virtual puro. Não é encorajado a utilizá-lo porque, ao empregar esse método, a classe pai torna-se abstrata, o que a torna inútil. A metodologia mais utilizada é o virtual destructor e é uma boa prática.

Saída:

Conclusão

Aprendemos sobre o destruidor virtual desde o conceito de OOP até os construtores e destruidores. Depois de explicar tudo isso, discutimos sobre o destruidor virtual em detalhes com exemplos de codificação e o destruidor virtual puro. Antes de explicar o destruidor virtual, devemos saber sobre os construtores, destruidores e herança. Na herança, herdamos as classes de uma classe pai. As classes filhas podem ser mais de uma, mas a classe pai é apenas uma. Destruidores virtuais e destruidores virtuais puros são aplicados na herança para evitar o vazamento de memória. Do exemplo básico ao exemplo avançado, abordamos tudo o que você deve saber para começar a usar e praticamente destruir a memória da classe derivada.