Junior — Middle
Milyen következmények léphetnek fel, ha egy virtuális függvényt hívunk egy objektum destruktorán belül?
sobes.tech MI
Válasz az MI-től
Amikor egy virtuális függvényt hívunk egy C++-ban lévő objektum destruktorán belül, akkor a hívás a destrukció során az aktuális típusnak megfelelő függvényverziót fogja eredményezni, nem a származtatott osztályét. Ez azért van, mert a destruktor futtatásakor az objektum már "szűkült" az alap osztályra, és a virtuális hívások mechanizmusa nem veszi figyelembe a származtatott osztályokat.
Következmények:
- Ha a virtuális függvényt a származtatott osztályban felülírták, akkor az alap osztály destruktorán belüli hívás nem fogja ezt a felülírt verziót meghívni, hanem az alap verziót.
- Ez váratlan viselkedéshez vagy hibákhoz vezethet, ha a függvény a származtatott osztály állapotától függ, amely már meg lett semmisítve.
Példa:
#include <iostream>
struct Base {
virtual ~Base() {
foo(); // virtuális függvény hívása
}
virtual void foo() { std::cout << "Base::foo" << std::endl; }
};
struct Derived : Base {
~Derived() override {
std::cout << "Derived destruktor" << std::endl;
}
void foo() override { std::cout << "Derived::foo" << std::endl; }
};
int main() {
Base* obj = new Derived();
delete obj; // meghívja a Base::~Base(), amelyben a foo() a Base::foo-t hívja
}
A kimenet:
Derived destruktor
Base::foo
Ezért a virtuális függvényhívás a destruktorban nem hívja meg a származtatott osztály felülírt verzióját.