Eu tenho um class A
que usa uma alocação de memória heap para um de seus campos. A classe A é instanciada e armazenada como um campo de ponteiro em outra classe ( class B
.
Quando termino com um objeto da classe B, eu chamo delete
, que eu suponho que chama de destruidor ... Mas isso também chama o destruidor da classe A?
Editar:
A partir das respostas, entendi (por favor, edite se estiver incorreto):
delete
de uma instância de B chama B :: ~ B ();- que chama
A::~A();
A::~A
deve explicitamentedelete
todas as variáveis de membro alocado-heap do objeto A;- Finalmente, o bloco de memória que armazena a instância da classe B é retornada ao heap - quando novo foi usado, ele primeiro alocou um bloco de memória no heap e depois chamou os construtores para inicializá-lo, agora que todos os destruidores foram chamados para finalizar o objeto. bloco em que o objeto residia é retornado ao heap.
fonte
++
operador nele. Então, eu me pergunto se o ponteiro que aponta no meio dos dados da classe ainda tem o efeito.Quando você chama delete em um ponteiro alocado por new, o destruidor do objeto apontado será chamado.
fonte
É nomeado "destruidor", não "desconstrutor".
Dentro do destruidor de cada classe, você deve excluir todas as outras variáveis de membro que foram alocadas com novas.
editar: para esclarecer:
Diga que você tem
Alocar uma instância de B e, em seguida, excluir é limpo, porque o que B aloca internamente também será excluído no destruidor.
Mas instâncias da classe C vazam memória, porque alocam uma instância de A que não libera (nesse caso, C nem sequer tem um destruidor).
fonte
Se você tiver um ponteiro comum (
A*
), o destruidor não será chamado (e a memória, porA
exemplo, também não será liberada), a menos que você o expliquedelete
explicitamenteB
. Se você deseja destruição automática, veja indicadores inteligentes comoauto_ptr
.fonte
Você deve excluir A você mesmo no destruidor de B.
fonte
Quando você faz:
O destruidor será chamado apenas se sua classe base tiver a palavra-chave virtual.
Então, se você não tivesse um destruidor virtual, apenas ~ B () seria chamado. Mas como você tem um destruidor virtual, primeiro ~ D () será chamado, depois ~ B ().
Nenhum membro de B ou D alocado no heap será desalocado, a menos que você os exclua explicitamente. E excluí-los também chamará seu destruidor.
fonte
Você tem algo como
Se você ligar
delete b;
, nada acontecerá com a e você terá um vazamento de memória. Tentar se lembrardelete b->a;
não é uma boa solução, mas existem outras.Este é um destruidor para B que excluirá a. (Se a é 0, essa exclusão não faz nada. Se a não é 0, mas não aponta para a memória de novo, você obtém corrupção de heap.)
Dessa forma, você não tem a como ponteiro, mas sim um auto_ptr <> (shared_ptr <> também serve, ou outros ponteiros inteligentes), e ele é excluído automaticamente quando b é.
Qualquer uma dessas maneiras funciona bem, e eu usei as duas.
fonte
Fiquei me perguntando por que o destruidor da minha classe não foi chamado. O motivo foi que eu esqueci de incluir a definição dessa classe (#include "class.h"). Eu só tive uma declaração como "classe A"; e o compilador ficou satisfeito com isso e deixe-me chamar "delete".
fonte
Não. O ponteiro será excluído. Você deve chamar a exclusão em A explícita no destruidor de B.
fonte
O destruidor para o objeto da classe A será chamado apenas se delete for chamado para esse objeto. Certifique-se de excluir esse ponteiro no destruidor da classe B.
Para obter mais informações sobre o que acontece quando a exclusão é chamada em um objeto, consulte: http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.9
fonte
não, ele não chamará destruidor para a classe A, você deve chamá-lo explicitamente (como PoweRoy disse), excluir a linha 'delete ptr;' no exemplo para comparar ...
fonte