Junior
Co víte o klíčovém slovu virtual v C++?
sobes.tech AI
Odpověď od AI
virtual v C++ slouží k deklaraci virtuálních funkcí v základní třídě. To umožňuje implementaci polymorfismu během běhu (runtime polymorphism).
Použití:
- Definuje funkci v základní třídě, kterou lze přepsat (override) v odvozených třídách.
- Při volání virtuální funkce přes ukazatel nebo odkaz na základní třídu je skutečně volána implementace funkce v objektu odvozené třídy (pokud je tam přepsána). To se děje během běhu pomocí tabulky virtuálních funkcí (vtable).
Hlavní body:
- Virtuální mohou být pouze členské funkce třídy. Globální funkce, statické členské funkce a konstruktory nemohou být virtuální.
- Destruktory mohou a často by měly být virtuální, aby se zabránilo únikům paměti při mazání objektů odvozených tříd přes ukazatel na základní třídu.
- Pokud je funkce deklarována
virtualv základní třídě, zůstává automaticky virtuální ve všech odvozených třídách, i když tam není explicitně použitovirtual(ačkoliv doporučuje se to uvádět explicitně pro jasnost). - Čistě virtuální funkce jsou deklarovány s
= 0a činí třídu abstraktní. Taková třída nemůže být přímo instanciována.
Pří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žití override pro jasné označení přepsání
std::cout << "From Derived" << std::endl;
}
~Derived() override { // Použití override
std::cout << "Derived destructor" << std::endl;
}
};
int main() {
Base* ptr = new Derived(); // Ukazatel na základní třídu ukazuje na objekt odvozené
ptr->print(); // Volá se Derived::print() kvůli virtuální funkci
delete ptr; // Volají se destruktory Derived a poté Base kvůli virtuálnímu destruktoru
return 0;
}
Související pojmy:
- vtable (tabulka virtuálních funkcí): Tabulka ukazatelů na virtuální funkce třídy. Každý objekt s virtuálními funkcemi obsahuje neviditelný ukazatel (vptr) na vtable své třídy.
- vptr (ukazatel na vtable): Nutný pro určení volané funkce během běhu.
= 0(čistá virtuální funkce): Znamená, že funkce nemá implementaci v této třídě, čímž se stává abstraktní.override(přepsání): Výslovně označuje, že funkce v odvozené třídě přepisuje virtuální funkci základní třídy. Pomáhá kompilátoru najít chyby, pokud se signatura funkce neshoduje.final(konec): Zakazuje další přepsání virtuální funkce nebo dědění od třídy.
Stručně: virtual je hlavní mechanismus pro implementaci polymorfismu přes dědičnost a dynamické vázání funkcí v C++.