Le funzioni virtuali sono presenti in C++ fin dall'inizio come mezzo di polimorfismo dinamico. Tuttavia, prima non esisteva un meccanismo sintattico che forzasse il compilatore a controllare la correttezza della ridefinizione delle funzioni virtuali nelle classi derivate. Dopo l'introduzione di C++11, la parola chiave override è diventata uno strumento di verifica aggiuntiva da parte del compilatore.
Senza override, il compilatore non garantisce che la funzione stia effettivamente ridefinendo un metodo della classe base. Errori nella firma (ad esempio, tipo errato o const) portano alla creazione di una nuova funzione nella classe derivata ("ombre"), il che rompe il polimorfismo e rende difficile il debug.
Usare override durante la dichiarazione di una funzione virtuale nella classe derivata consente al compilatore di verificare che la firma corrisponda esattamente a quella della funzione virtuale padre, e che la funzione sta effettivamente ridefinendo il padre. Altrimenti, la compilazione si interrompe con un errore.
Esempio di codice:
struct Base { virtual void foo() const {} }; struct Derived : Base { void foo() const override { /* implementazione */ } };
Se in Derived scriviamo void foo() senza const override, il compilatore genererà un errore.
Caratteristiche principali:
È possibile lasciare una funzione virtuale con la parola chiave 'override', ma senza la parola chiave 'virtual'?
Sì, override implica che la funzione sia virtuale. Indicare virtual insieme a override è ridondante, ma non vietato.
È possibile avere un errore se la funzione differisce solo per un modificatore const o ref qualifier (ad esempio, & o &&)?
Sì, qualsiasi differenza nella firma, inclusi const/riferimenti, interrompe la ridefinizione. Ad esempio, void foo() override non ridefinisce void foo() const, e il compilatore grazie a override lo catturerà.
È possibile applicare 'override' a funzioni statiche o costruttori?
No. override è solo per funzioni virtuali, non può essere applicato a funzioni statiche, costruttori, distruttori (se non sono virtuali).
In un grande progetto, la classe derivata ha un errore di battitura nella firma della funzione: la funzione in realtà non è override, ma lo sviluppatore la considera tale, il polimorfismo non funziona come previsto.
Vantaggi:
Svantaggi:
In tutte le classi derivate si usa override, i test catturano errori già al momento della compilazione.
Vantaggi:
Svantaggi: