Per quanto ho capito, l'introduzione della override
parola chiave in C ++ 11 non è altro che un controllo per assicurarsi che la funzione implementata sia l' override
ing di una virtual
funzione nella classe base.
È così?
Per quanto ho capito, l'introduzione della override
parola chiave in C ++ 11 non è altro che un controllo per assicurarsi che la funzione implementata sia l' override
ing di una virtual
funzione nella classe base.
È così?
Risposte:
Questa è davvero l'idea. Il punto è che sei esplicito su cosa intendi, in modo che un errore altrimenti silenzioso possa essere diagnosticato:
struct Base
{
virtual int foo() const;
};
struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};
Il codice sopra riportato viene compilato, ma non è ciò che si potrebbe significare (notare ciò che manca const
). Se invece dicessi, virtual int foo() override
otterrai un errore del compilatore secondo cui la tua funzione non sta di fatto sostituendo nulla.
override
funzionalità "risolve" questo; devi ricordarti di usarlo, proprio come avresti dovuto ricordare di scrivere il const
;)
explicit
le definizioni di classe non sono diventate C ++ 11. Huh.
explicit
definizione di classe? Non ne ho mai sentito parlare.
override
quando si intende farlo) è più probabile che ricordare casi angolari, cioè non c'è generalità nella copia di funzioni di diversi prototipi, solo irregolarità come la mancanza const
o la scrittura char
invece di int
, ecc.
override
specificatore è menzionato in questa risposta , che è più futuristica che immediata. La risposta suggerisce che, mantieni override
il virtual
metodo. In futuro, quando si cambia erroneamente la firma, la sua utilità entra in gioco.
Citazione di Wikipedia:
L'identificatore speciale di override indica che il compilatore controllerà le classi di base per verificare se esiste una funzione virtuale con questa firma esatta. E in caso contrario, il compilatore si spegnerà.
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Modifica (tentando di migliorare un po 'la risposta):
Dichiarare un metodo come "override" significa che quel metodo è destinato a riscrivere un metodo (virtuale) sulla classe base. Il metodo di sostituzione deve avere la stessa firma (almeno per i parametri di input) del metodo che intende riscrivere.
Perché è necessario? Bene, vengono evitati i seguenti due casi di errore comuni:
si digita male un tipo nel nuovo metodo. Il compilatore, ignaro del fatto che intende scrivere un metodo precedente, lo aggiunge semplicemente alla classe come nuovo metodo. Il problema è che il vecchio metodo è ancora lì, il nuovo viene aggiunto solo come sovraccarico. In questo caso, tutte le chiamate verso il vecchio metodo funzioneranno come prima, senza alcun cambiamento nel comportamento (che sarebbe stato lo scopo stesso della riscrittura).
si dimentica di dichiarare il metodo nella superclasse come "virtuale", ma si tenta ancora di riscriverlo in una sottoclasse. Mentre questo apparentemente sarà accettato, il comportamento non sarà esattamente come previsto: il metodo non è virtuale, quindi l'accesso attraverso i puntatori verso la superclasse terminerà chiamando il vecchio metodo (superclasse ') invece del nuovo metodo (sottoclasse').
L'aggiunta di "override" chiarisce chiaramente ciò: attraverso questo, si sta dicendo al compilatore che tre cose si aspettano:
Se uno di questi è falso, viene segnalato un errore.
* nota: il parametro di output è talvolta di tipo diverso, ma correlato. Leggi le trasformazioni covarianti e controverse se interessati.
Trovato " override " è utile quando qualcuno ha aggiornato la firma del metodo virtuale della classe base come l'aggiunta di un parametro facoltativo ma ha dimenticato di aggiornare la firma del metodo della classe derivata. In tal caso i metodi tra la base e la classe derivata non sono più una relazione polimorfica. Senza la dichiarazione di sostituzione, è difficile scoprire questo tipo di bug.
override
sia un ottimo modo per scoprire tali problemi, dovrebbe essere utile anche una buona copertura dei test unitari.
Sì, è così. È un controllo per assicurarsi che non si provi una sostituzione e si rovini con una firma mal riuscita. Ecco una pagina Wiki che spiega questo in dettaglio e ha un breve esempio illustrativo:
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Bozza standard C ++ 17
Dopo aver esaminato tutti gli override
hit della bozza standard C ++ 17 N4659 , l'unico riferimento che posso trovare override
all'identificatore è:
5 Se una funzione virtuale è contrassegnata con l'override di virt-specifier e non sovrascrive una funzione membro di una classe base, il programma è mal formato. [ Esempio:
struct B { virtual void f(int); }; struct D : B { virtual void f(long) override; // error: wrong signature overriding B::f virtual void f(int) override; // OK }
- fine esempio]
quindi penso che possibilmente far esplodere programmi sbagliati sia in realtà l'unico effetto.