Ako zavolať čistú virtuálnu metódu?
sobes.tech AI
Odpoveď od AI
Nie je možné priamo volať čistú virtuálnu metódu cez ukazovateľ na abstraktnú základnú triedu alebo cez objekt tejto triedy, pretože nemá definíciu v základnej triede.
Avšak, čistá virtuálna metóda môže byť volaná z konštruktora alebo deštruktora odvodenej triedy, v ktorej má táto metóda implementáciu. V takom prípade bude volanie povolené v statickom režime a bude zavolaná implementácia tejto triedy, v ktorej sa volanie vykonáva.
Príklad volania z konštruktora odvodenej triedy:
#include <iostream>
class Base {
public:
virtual void pure_virtual_method() = 0; // Čistá virtuálna metóda
};
class Derived : public Base {
public:
void pure_virtual_method() override {
std::cout << "Implementácia v Derived\n";
}
Derived() {
// Volanie čistej virtuálnej metódy z konštruktora odvodenej triedy
pure_virtual_method();
}
};
int main() {
Derived obj; // Vytvorenie objektu odvodenej triedy, ktorý volá konštruktor
return 0;
}
V tomto príklade, pri vytvorení objektu obj triedy Derived, bude zavolaný konštruktor Derived, v ktorom sa vykoná volanie pure_virtual_method(). Pretože v triede Derived je táto metóda implementovaná, bude úspešne zavolaná.
Pri pokuse volať čistú virtuálnu metódu z konštruktora alebo destruktora abstraktnej základnej triedy, v ktorej je deklarovaná, dôjde k správaniu nevyhradenému (undefined behavior), pretože v čase vykonávania konštruktora alebo destruktora ešte nie je vtable základnej triedy úplne vytvorená alebo je už zničená, a príslušná implementácia v odvodenej triede nie je dostupná.
Tiež je možné volať čistú virtuálnu metódu z odvodenej triedy pomocou kvalifikácie oblasti viditeľnosti (Base::pure_virtual_method()), ale to je možné len z implementácie čistej virtuálnej metódy v odvodenej triede, ak volá implementáciu z základnej triedy (čo pre čistú virtuálnu metódu nie je platné), alebo inú funkciu, ktorá volá čistú virtuálnu metódu (čo tiež vedie k nevyhradenému správaniu), alebo pre volanie nevirtuálnej metódy s rovnakým menom z základnej triedy.
Správny spôsob práce s logikou, reprezentovanou čistou virtuálnou metódou, je vytvorenie objektu odvodenej triedy a volanie tejto logiky cez ukazovateľ alebo odkaz na základnú triedu (polymorfizmus).
#include <iostream>
class Base {
public:
virtual void pure_virtual_method() = 0;
};
class Derived : public Base {
public:
void pure_virtual_method() override {
std::cout << "Implementácia v Derived cez polymorfizmus\n";
}
};
int main() {
Base* ptr = new Derived(); // Polymorfné volanie
ptr->pure_virtual_method();
delete ptr;
return 0;
}
Takže, "voliť čistú virtuálnu metódu" v bežnom zmysle (cez objekt alebo ukazovateľ na základnú triedu, ktorá nemá definíciu) nie je možné. Volanie je možné iba z konštruktora alebo destruktora odvodenej triedy s jej implementáciou, alebo nepriamo, cez polymorfizmus, vytvorením objektu odvodenej triedy.