2013-02-25 16 views
7

ora sto imparando ++ C, il lato OO, e ho avuto tutto il tempo:differenza C++ tra virtuale = 0; e la funzione vuoto

class SomeClass{ 
    virtual void aMethod()=0; 
} 

class AnotherClass{ 
    void anotherMethod(){/*Empty*/} 
} 

class SomeClassSon : public SomeClass{ 
    void aMethod(){/*Also Empty*/} 
} 

Il mio dubbio è: qual è la differenza tra i 3 metodi. Il virtuale è uguale a zero, quello vuoto e il virtuale, poiché è ereditato, vuoto.

Perché non posso solo fare il metodo SomeClassSon come il padre (virtual void è uguale a zero?)

+0

'SomeClass s; s.aMethod() 'non è una chiamata valida. – andre

+3

La differenza è, con '= 0' nella classe base, ogni classe derivata * deve * implementare il metodo. –

+2

@DavidSchwartz - deve implementare la funzione * se la classe è istanziata *. Se la funzione non è implementata, la classe è astratta. –

risposta

10

Per la vostra

class SomeClass{ 
    virtual void aMethod()=0; 
} 

la presenza di un puro metodo virtualerende la classe astratta . Una volta che hai uno di questi metodi virtuali puri, =0, nella tua classe, non puoi creare un'istanza della classe. Inoltre, ogni classe derivata deve implementare il puro virtual aMethod() oppure diventa anche una classe astratta.

Nella classe derivata, si sovrascrive il metodo virtuale puro dall'alto e ciò rende la classe derivata non astratta. È possibile creare un'istanza di questa classe derivata.

Ma, nella classe derivata, il corpo del metodo è vuoto, giusto? Ecco perché la tua domanda ha un senso: perché non rendere la classe pure virtuale. Bene, la tua classe può comportare altri metodi. In tal caso, non è possibile creare un'istanza SomeClass (esiste un metodo virtuale puro), mentre la classe figlio SomeClassSon può essere.

Lo stesso vale per lo AnotherClass, che può essere istanziato, in contrasto con SomeClass.

6

La differenza è che virtual void aMethod() = 0 è un pure virtual function, il che significa che:?

  1. SomeClass diventa un classe base astratta, significa che non può essere istanziata.
  2. Qualsiasi classe che eredita da SomeClass deve attuare aMethod, o troppo diventa una classe base astratta che non può essere istanziata

noti che qualsiasi classe con uno o più puri funzioni virtuali è automaticamente una classe base astratta.

+1

Forse intendevi la cosa giusta, ma hai detto male: le classi derivate da 'SomeClass' non * sono * costrette a implementare la funzione, ma se non lo fanno sono anche astratte. –

1

Un puro virtual rende astratta la classe. Un metodo vuoto non virtuale non fa nulla: porta semplicemente a un errore del linker se si tenta di chiamarlo. Al contrario, non puoi tentare di chiamare un puro virtual (a meno che tu non provi a chiamarlo da un costruttore, che comunque è male) perché il compilatore non ti permetterà di creare quell'oggetto.

C'è anche una differenza logica: il metodo contrassegnato con virtual sarà virtuale attraverso la catena di ereditarietà, gli altri sono solo metodi regolari.

1

Una pura funzione virtuale (il primo esempio, con =0) indica che la funzione deve essere sovrascritta in una classe derivata affinché un oggetto di tale classe sia istanziato.

Il secondo è fondamentalmente solo una funzione membro che non fa nulla. Poiché la funzione ha un nome diverso e la classe non è correlata a SomeClass, i due non si influenzano a vicenda.

Il terzo sovrascrive la pura funzione virtuale, quindi è possibile istanziare SomeClassSon, ma nella classe derivata la funzione ignorata non fa nulla.

2

la dichiarazione aMethod() = 0 indica al compilatore che questo metodo deve essere fornito in sottoclassi. Qualsiasi sottoclasse che non implementa il metodo non può essere istanziata. Questo ti aiuta a garantire che qualsiasi oggetto della classe base abbia il metodo implementato.

3

Il "uguale a 0" a cui ci si riferisce si chiama "virtuale puro". È una funzione che il bambino che vuole essere istanziato deve implementare invece di fornire una funzionalità di base che significa che la classe genitore sta per definire la funzionalità che deve esistere ma che il genitore non ha alcuna conoscenza di come il bambino lo farà. Nota che questo rende la classe astratta in quanto non può essere istanziata. Per esempio, potrei voler definire una classe "Mammifero" da cui posso ereditare e voglio che i suoi figli agiscano in un certo modo - ma non posso semplicemente creare un "Mammifero". Invece creerei una classe "Giraffe" e farò in modo che si comporti come dovrebbe.

Viene anche spiegato in questa domanda SO.

La funzione "Vuoto" a cui ci si riferisce è invece funzionalità in cui la funzione è definita e può essere chiamata, ma non fa nulla.

Problemi correlati