Co je virtuální funkce?
Virtuální funkce je funkce definovaná v nadřazené třídě, která musí být přítomna v podtřídě, aby měla tato podtřída úplnou definici třídy. Virtuální funkce se spoléhají na objektově orientované programovací paradigma zvané virtuální dědičnost, které je nejčastěji vidět v C ++ pomocí klíčového slova „virtuální“. Pro definování virtuální funkce jsou nutné dvě třídy: nadtřída a podtřída. Nadřazená třída je místo, kde je funkce nejprve deklarována a případně definována. Podtřída je místo, kde je funkce definována - nebo přepsána v závislosti na tom, zda byla funkce definována v nadřazené třídě.
Virtuální funkce lze definovat jedním ze dvou způsobů. Nejprve to může být definováno jako pahýl, ve kterém má prázdné tělo a nedělá nic. Zadruhé by to mohlo být definováno jako čistě virtuální funkce, kde je definována jako NULL v hlavičkovém souboru nadřazené třídy.
Obě metodiky mají své výhody i nevýhody. Definování funkce jako výhonek zajišťuje, že všechny podtřídy mají nějakou implementaci, i když nic nedělá. Pokud však zapomenete přepsat funkci a správně ji implementovat do podtřídy, neobjeví se žádné chyby ani varování, která by na to poukazovala. Definování čistě virtuální funkce na druhé straně vyžaduje, aby každá podtřída měla svou vlastní definici funkce, a pokud tomu tak není, objeví se chyby.
Virtuální funkce však podléhají stejným pravidlům dědičnosti jako ne virtuální funkce, takže hierarchie dědičnosti s více než dvěma úrovněmi nemusí vyžadovat explicitní definice virtuálních funkcí. Například lze uvažovat o třídě A, která deklaruje virtuální funkci, která je implementována v podtřídě B. Třída B má vlastní podtřídu, třída C. Třída C nevyžaduje výslovnou definici funkce třídy A, protože zdědí definice ze třídy B. Je-li to nutné, třída C by mohla potlačit funkci třídy B nebo by mohla potlačit funkci třídy B a zároveň ji také volat.
V opačném případě nemusí být virtuální funkce definovány v podtřídě, pokud jsou v této podtřídě deklarovány jako virtuální. Například lze uvažovat o třídě A, která deklaruje virtuální funkci a má dvě podtřídy, B a C. Navíc si lze představit, že třída B má podtřídy D a E a podtřída C má podtřídy F a G.
Všechny třídy B až G musí mít nějak definovanou virtuální funkci třídy A. Pokud má třída B implementaci funkce A, třídy D a E ji nepotřebují k přepracování. Možná podtřídy C musí implementovat funkci A, ale obě dělají něco jiného, takže definování funkce ve třídě C by nebylo užitečné. V takovém případě může být funkce prohlášena za virtuální ve třídě C a implementace není nutná.
Virtuální funkce se mohou učit, ale při správném používání mohou snížit duplicitu kódu a obecně usnadnit pochopení kódu. Existuje však mnoho úskalí s virtuálními funkcemi, zejména pokud jde o vícenásobnou dědičnost. Ve vícenásobném dědictví je možné, že nejasně definované virtuální funkce jsou ve vzájemném konfliktu, takže by v tomto kontextu měly být používány s opatrností.