2011-06-18 35 views
11

Cosa fa la parola chiave virtuale quando si sostituisce un metodo? Non sto usando e tutto funziona bene.Che cosa significa la parola chiave virtuale quando si sostituisce un metodo?

Ogni compilatore si comporta allo stesso modo a questo proposito?

Devo usarlo o no?

+0

possibile duplicato del [C++ virtuale/virtuale pura Spiegato] (http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained) –

+0

@Harald: Nope. Argomento diverso – Xeo

+0

Ma sto chiedendo sull'utilizzo di quella parola chiave. Non riguardo al metodo virtuale astratto. – kravemir

risposta

11

Non è possibile sostituire una funzione membro senza di essa.

È possibile solo nascondere uno.

struct Base { 
    void foo() {} 
}; 

struct Derived : Base { 
    void foo() {} 
}; 

Derived::foo fa non di override Base::foo; semplicemente nasconde perché ha lo stesso nome, in modo tale che la seguente:

Derived d; 
d.foo(); 

invoca Derived::foo.

virtual consente il polimorfismo tale che si realtà funzioni di override:

struct Base { 
    virtual void foo() {} 
}; 

struct Derived : Base { 
    virtual void foo() {} // * second `virtual` is optional, but clearest 
}; 

Derived d; 
Base& b = d; 
b.foo(); 

Questo richiama Derived::foo, perché questo ora overrideBase::foo — l'oggetto è polimorfico.

(È inoltre necessario da usare riferimenti o puntatori per questo, a causa di the slicing problem.)


  • Derived::foo non ha bisogno di ripetere la parola virtual perché Base::foo ha già usato. Questo è garantito dallo standard e puoi fare affidamento su di esso. Tuttavia, alcuni pensano che sia meglio tenerlo per chiarezza.
+2

So che virtuale è necessario quando si dichiara un metodo che può essere sovrascritto. Ho chiesto informazioni sull'utilizzo di questa parola chiave durante l'override del metodo, non sulla dichiarazione. – kravemir

+1

@Miro: non seguo. Esegui l'override di una funzione dichiarandone un'altra che la sovrascrive. Ad ogni modo, almeno il mio ultimo paragrafo risponde alla tua domanda. –

8

Un metodo virtual nella classe base si sovrapporrà nella gerarchia, rendendo anche ogni metodo di sottoclasse con la stessa firma virtual.

class Base{ 
public: 
    virtual void foo(){} 
}; 

class Derived1 : public Base{ 
public: 
    virtual void foo(){} // fine, but 'virtual' is no needed 
}; 

class Derived2 : public Base{ 
public: 
    void foo(){} // also fine, implicitly 'virtual' 
}; 

io consiglierei di scrivere il virtual però, se a scopo di documentazione solo.

5

Quando una funzione è virtuale, rimane virtuale in tutta la gerarchia, indipendentemente dal fatto che specifichi esplicitamente ogni volta che è virtuale. Quando si esegue l'override un metodo, utilizzare virtuale al fine di essere più espliciti - nessun altra differenza :)

class A 
{ 
    virtual void f() 
    { 
     /*...*/ 
    }; 
}; 

class B:public A; 
{ 
    virtual void f() //same as just void f() 
    { 
     /*...*/ 
    }; 
}; 
Problemi correlati