Junior — Middle
Aké dôsledky môžu nastať pri volaní virtuálnej funkcie vo vnútri deštruktora objektu?
sobes.tech AI
Odpoveď od AI
Keď sa volá virtuálna funkcia vo vnútri destruktora objektu v C++, volá sa verzia funkcie, ktorá zodpovedá aktuálnemu typu objektu v štádiu ničenia, a nie odvodená trieda. To je spôsobené tým, že počas vykonávania destruktora je objekt už "zúžený" na základnú triedu a mechanizmus virtuálnych volaní nezohľadňuje odvodené triedy.
Dôsledky:
- Ak bola virtuálna funkcia prepísaná v odvodenom triede, volanie vnútri destruktora základnej triedy nevyvolá túto prepísanú verziu, ale základnú.
- To môže viesť k nečakanému správaniu alebo chybám, ak funkcia závisí od stavu odvodeného triedy, ktorá už bola zničená.
Príklad:
#include <iostream>
struct Base {
virtual ~Base() {
foo(); // volanie virtuálnej funkcie
}
virtual void foo() { std::cout << "Base::foo" << std::endl; }
};
struct Derived : Base {
~Derived() override {
std::cout << "Deštruktor Derived" << std::endl;
}
void foo() override { std::cout << "Derived::foo" << std::endl; }
};
int main() {
Base* obj = new Derived();
delete obj; // zavolá Base::~Base(), v ktorom foo() zavolá Base::foo
}
Výstup bude:
Deštruktor Derived
Base::foo
Preto volanie virtuálnej funkcie v destruktoru nevolá prepísanú verziu z odvodeného triedy.