Sobes.tech
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.