Junior — Middle
Que consequências podem ocorrer ao chamar uma função virtual dentro do destruidor de um objeto?
sobes.tech IA
Resposta da IA
Ao chamar uma função virtual dentro do destruidor de um objeto em C++, é chamada a versão da função que corresponde ao tipo atual do objeto na fase de destruição, e não à da classe derivada. Isto deve-se ao facto de, durante a execução do destruidor, o objeto já ter sido "reduzido" à classe base, e o mecanismo de chamadas virtuais não considera as classes derivadas.
Consequências:
- Se a função virtual foi sobrescrita na classe derivada, a chamada dentro do destruidor da classe base não invocará essa versão sobrescrita, mas a versão base.
- Isto pode levar a comportamentos inesperados ou erros se a função depender do estado da classe derivada, que já foi destruído.
Exemplo:
#include <iostream>
struct Base {
virtual ~Base() {
foo(); // chamada a função virtual
}
virtual void foo() { std::cout << "Base::foo" << std::endl; }
};
struct Derived : Base {
~Derived() override {
std::cout << "Destruidor de Derived" << std::endl;
}
void foo() override { std::cout << "Derived::foo" << std::endl; }
};
int main() {
Base* obj = new Derived();
delete obj; // chamará Base::~Base(), dentro do qual foo() chamará Base::foo
}
A saída será:
Destruidor de Derived
Base::foo
Portanto, a chamada de uma função virtual no destruidor não invoca a versão sobrescrita da classe derivada.