Sobes.tech
Junior

Čo viete o kľúčovom slove virtual v C++?

sobes.tech AI

Odpoveď od AI

virtual v C++ sa používa na deklaráciu virtuálnych funkcií v základnej triede. To umožňuje implementovať polymorfizmus počas behu (runtime polymorphism).

Použitie:

  • Definuje funkciu v základnej triede, ktorú je možné prepísať (override) v odvodených triedach.
  • Pri volaní virtuálnej funkcie cez ukazovateľ alebo odkaz na základnú triedu sa skutočne volá implementácia funkcie v objekte odvodeného triedy (ak je tam prepísaná). To sa deje počas behu pomocou tabuľky virtuálnych funkcií (vtable).

Hlavné body:

  • Virtuálne môžu byť iba členské funkcie triedy. Globálne funkcie, statické členské funkcie a konštruktory nemôžu byť virtuálne.
  • Destruktory môžu a často by mali byť virtuálne, aby sa zabránilo únikom pamäti pri mazaní objektov odvodených tried cez ukazovateľ na základnú triedu.
  • Ak je funkcia deklarovaná virtual v základnej triede, automaticky zostáva virtuálna vo všetkých odvodených triedach, aj keď tam nie je explicitne použitý virtual (hoci sa odporúča to uvádzať explicitne pre jasnosť).
  • Čisté virtuálne funkcie sú deklarované s = 0 a robia triedu abstraktnou. Takú triedu nie je možné priamo inštanciovať.

Príklad:

#include <iostream>

class Base {
public:
    virtual void print() {
        std::cout << "From Base" << std::endl;
    }

    virtual ~Base() {
        std::cout << "Base destructor" << std::endl;
    }
};

class Derived : public Base {
public:
    void print() override { // Použitie override na jasné označenie prepísania
        std::cout << "From Derived" << std::endl;
    }

    ~Derived() override { // Použitie override
        std::cout << "Derived destructor" << std::endl;
    }
};

int main() {
    Base* ptr = new Derived(); // Ukazovateľ na základnú triedu ukazuje na objekt odvodený

    ptr->print(); // Volá sa Derived::print() kvôli virtuálnej funkcii
    delete ptr;   // Volajú sa destruktory Derived a potom Base kvôli virtuálnemu destruktoru

    return 0;
}

Súvisiace pojmy:

  • vtable (tabuľka virtuálnych funkcií): Tabuľka ukazovateľov na virtuálne funkcie triedy. Každý objekt s virtuálnymi funkciami obsahuje neviditeľný ukazovateľ (vptr) na vtable svojej triedy.
  • vptr (ukazovateľ na vtable): Nevyhnutný na určenie volanej funkcie počas behu.
  • = 0 (čistá virtuálna funkcia): Znamená, že funkcia nemá implementáciu v tejto triede, čím sa stáva abstraktnou.
  • override (prepísanie): Výslovne označuje, že funkcia v odvodenom triede prepíše virtuálnu funkciu základnej triedy. Pomáha kompilátoru nájsť chyby, ak sa signatúra funkcie nezhoduje.
  • final (koniec): Zakazuje ďalšie prepísanie virtuálnej funkcie alebo dedenie od triedy.

Stručne: virtual je hlavný mechanizmus na implementáciu polymorfizmu cez dedičstvo a dynamické viazanie funkcií v C++.