La parola chiave 'override' è solo un controllo per un metodo virtuale override?


226

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ì?



13
Non è un doppio controllo però. È l'unico controllo.
Nikos C.

13
hey, override NON è una parola chiave, è una specie di zucchero grammaticale. int override = 42; // OK
KAlO2

2
Migliora inoltre la leggibilità spiegando che la funzione dichiarata viene ignorata;)
mots_g

5
Quindi, quando ... C ++ 11 diventerà abbastanza standard da iniziare a insegnare cose come questa nel mio locale di 4 anni? Quando lo sapranno ?!
Cinch

Risposte:


263

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.


74
+1: Anche se, sfortunatamente, è un po 'un'aringa rossa quando le persone suggeriscono che la nuova overridefunzionalità "risolve" questo; devi ricordarti di usarlo, proprio come avresti dovuto ricordare di scrivere il const;)
Lightness Races in Orbit

Ho appena realizzato che explicitle definizioni di classe non sono diventate C ++ 11. Huh.
aschepler,

1
@aschepler E cosa farebbe una explicitdefinizione di classe? Non ne ho mai sentito parlare.
Christian Rau,

18
@LightnessRacesinOrbit: Sì, non è infallibile; tuttavia, ricordare una regola generale (di scrivere follemente 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.
legends2k

1
@Light, il miglior caso d'uso di 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.
iammilind

35

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:

  1. 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).

  2. 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:

  1. esiste un metodo con lo stesso nome nella superclasse
  2. questo metodo nella superclasse è dichiarato "virtuale" (ciò significa che deve essere riscritto)
  3. il metodo nella superclasse ha la stessa firma (input *) del metodo nella sottoclasse (il metodo di riscrittura)

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.


31

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.


1
+1. Sebbene overridesia un ottimo modo per scoprire tali problemi, dovrebbe essere utile anche una buona copertura dei test unitari.
Disilluso il

1
Questo è esattamente il motivo per cui sono così entusiasta di quel nuovo identificatore. L'unico problema è che questa funzione deve essere già applicata per prevenire errori causati da cambiamenti nelle classi di base. ;-)
Lupo,


2

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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.