10

Il seguente codice potrebbe ancora essere influenzato negativamente dalla mancanza di ereditarietà virtuale?L'ereditarietà virtuale è ancora necessaria quando le classi di base non contengono membri di dati?

Se è così, sarebbero gli effetti negativi essere lo stesso (o così male come) gli effetti negativi di ereditarietà multipla senza eredità virtuale se class Aha contenere membri di dati?

class A 
{ 
public : 
    virtual ~A () { } 
    virtual int foo () const = 0 ; 
} ; 

class B : public A 
{ 
public : 
    virtual ~B () { } 
} ; 

class C : public A 
{ 
public : 
    virtual ~C () { } 
} ; 

class D : public B , public C 
{ 
public : 
    virtual int foo () const { return 12 ; } 
} ; 
+1

E sembra [come si ha bisogno del 'virtual' vedere qui] (http://coliru.stacked-crooked.com/view?id=8bd2970b897e9b44), ovvero se si prevede che un puntatore a A derivato da B abbia lo stesso valore come se fosse derivato da C. – Niall

+1

in questo modo, devi dichiarare un distruttore virtuale con un'implementazione vuota in A. Vedi http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – Notinlist

+0

@Notinlist Grazie per la cattura. Ho aggiunto i distruttori virtuali ad A, B e C per sicurezza. – Giffyguy

risposta

4

Supponendo che si desidera utilizzare A come interfaccia generale, se non si effettua l'eredità virtuale che non sarebbe in grado di fare qualcosa di simile, perché ci sono due percorsi eredità al classe di base A dal bambino D:

int main() 
{ 
    D d; 
    const A& a = d; 

    std::cout << a.foo() << " " << d.foo() << " " << std::endl; 
} 

Se non è necessario utilizzare un D come A allora (a) Perché hai come una base astratta, in primo luogo e (B) n , non è necessario che l'ereditarietà sia virtuale.

1
class B : public virtual A { } ; 
class C : public virtual A { } ; 

Utilizzando l'ereditarietà virtuale sulle classi intermedie, la classe D avrà solo una singola istanza di classe A, e il tuo codice verrà compilato bene

Problemi correlati