Per quanto ho capito, l'introduzione della overrideparola chiave in C ++ 11 non è altro che un controllo per assicurarsi che la funzione implementata sia l' overrideing di una virtualfunzione nella classe base.
È così?
Per quanto ho capito, l'introduzione della overrideparola chiave in C ++ 11 non è altro che un controllo per assicurarsi che la funzione implementata sia l' overrideing di una virtualfunzione 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() overrideotterrai un errore del compilatore secondo cui la tua funzione non sta di fatto sostituendo nulla.
overridefunzionalità "risolve" questo; devi ricordarti di usarlo, proprio come avresti dovuto ricordare di scrivere il const;)
explicitle definizioni di classe non sono diventate C ++ 11. Huh.
explicitdefinizione di classe? Non ne ho mai sentito parlare.
overridequando 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 consto la scrittura charinvece di int, ecc.
overridespecificatore è menzionato in questa risposta , che è più futuristica che immediata. La risposta suggerisce che, mantieni overrideil virtualmetodo. 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.
overridesia 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 overridehit della bozza standard C ++ 17 N4659 , l'unico riferimento che posso trovare overrideall'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.