2013-08-12 13 views
102

Sono un principiante in C++. Ho trovato la parola chiave override utilizzata nel file di intestazione su cui sto lavorando. Posso sapere, che cosa è l'uso reale di override, forse con un esempio sarebbe facile da capire.Per che cosa si usa la parola chiave 'override' in C++?

+0

nota anche C++ 11 ha introdotto la parola 'final'. –

+8

@JesseGood e ancora: 'final' __anche non è una parola chiave__ !!! – zaufi

+1

@zaufi: Sì, ho imparato qualcosa di nuovo. I + 1ed la tua risposta. –

risposta

185

Il override parola chiave serve a due scopi:

  1. mostra al lettore del codice che "questo è un metodo virtuale, che è prevalente un metodo virtuale della classe di base."
  2. Il compilatore sa anche che è un override, quindi può "verificare" che non si stiano modificando/aggiungendo nuovi metodi che si ritiene siano prioritari.

Per spiegare quest'ultimo:

class base 
{ 
    public: 
    virtual int foo(float x) = 0; 
}; 


class derived: public base 
{ 
    public: 
    int foo(float x) override { ... do stuff with x and such ... } 
} 

class derived2: public base 
{ 
    public: 
    int foo(int x) override { ... } 
}; 

Nel derived2 il compilatore emetterà un errore per "cambiare il tipo". Senza override, al massimo il compilatore darebbe un avvertimento per "stai nascondendo il metodo virtuale con lo stesso nome".

+0

non dovrebbe l'intestazione di funzione per * foo * essere simile in classe * derived2 * ?? Ho compilato questo con VS2017 e ho ottenuto un errore di compilazione. Voglio dire che in * derived2 * * foo's * deve essere intestazione: * int foo (float x) override {...} * –

+8

Uhm, questo è interamente il punto, l'esempio di codice mostra come l'override può essere usato per rilevare un errore! –

+0

Penso che # 3 è che l'override può essere usato per rilevare la funzione to-be-overridden (che appartiene alla classe genitore/interfaccia) viene rimossa (non alternata). Ciò è utile se la sottoclasse sta aspettando una richiamata, ma non accadrà mai a causa della modifica della libreria, ecc. – Hei

4

override è una parola chiave C++ 11 che significa che un metodo è un "override" da un metodo di una classe base. Considerate questo esempio:

class Foo 
    { 
    public: 
     virtual void func1(); 
    } 

    class Bar : public Foo 
    { 
    public: 
     void func1() override; 
    } 

Se B :: FUNC1() firma non è uguale a firma A :: FUNC1() un errore di compilazione verrà generato perché B :: FUNC1() non sovrascrive A :: func1(), definirà invece un nuovo metodo chiamato func1().

+5

In base alle specifiche C++, "override" è un "identificatore con significato speciale". Ma queste cose in C# sono chiamate parole chiave contestuali. –

0

Wikipedia dice:

Metodo di primaria importanza, in programmazione orientata agli oggetti, è una caratteristica del linguaggio che permette una classe sottoclasse o un bambino per fornire una specifica implementazione di un metodo che viene già fornita da una delle sue superclassi o classi genitore.

In dettaglio, quando si ha un foo oggetto che ha un vuoto ciao) Funzione (:

class foo { 
    virtual void hello(); // Code : printf("Hello!"); 
} 

Un bambino di foo, avrà anche una) funzione ciao (:

class bar : foo { 
    // no functions in here but yet, you can call 
    // bar.hello() 
} 

Tuttavia, è possibile stampare "Hello Bar!" quando la funzione hello() viene chiamata da un oggetto bar. È possibile farlo utilizzando esclusione

class bar : foo { 
    virtual void hello() override; // Code : printf("Hello Bar!"); 
} 
+4

Non è necessario l'identificatore di override per farlo in C++, ma semplicemente impone che lo stai facendo correttamente. – Goose

43

e come addendum a tutti risponde, FYI: overridenon è una parola chiave, ma un speciale tipo di identificatore! Ha significato solo nel contesto della dichiarazione/definizione delle funzioni virtuali, in altri contesti è solo un identificatore ordinario . Per dettagli vedi 2.11.2 di Standard.

// kate: hl C++11; 
#include <iostream> 

struct base 
{ 
    virtual void foo() = 0; 
}; 

struct derived : base 
{ 
    virtual void foo() override 
    { 
     std::cout << __PRETTY_FUNCTION__ << std::endl; 
    } 
}; 

int main() 
{ 
    base* override = new derived(); 
    override->foo(); 
    return 0; 
} 

uscita:

[email protected] /work/tests $ g++ -std=c++11 -o override-test override-test.cc 
[email protected] /work/tests $ ./override-test 
virtual void derived::foo() 
+3

Funziona (qui e per 'final') perché non è possibile utilizzare identificatori regolari in cui posizionare queste parole chiave contestuali. – CTMacUser

+0

perchè diavolo non è proibito? –

+2

@FerencDajka 1. Perché dovrebbe essere? 2. Aggiungendo improvvisamente una nuova parola chiave (cioè vietandone l'uso ovunque altrove) si romperebbe la compatibilità all'indietro. – idmean

Problemi correlati