2013-09-07 26 views
12

Ho intenzione di creare un'interfaccia (piuttosto una classe base virtuale in C++) con un metodo che accetta un argomento del proprio tipo.Tipo di parametro funzione override con tipo di classe derivata

class Base { 
public: 
    virtual void seriousMethod(const Base &arg) = 0; 
} 

La classe derivata non dovrebbe tuttavia prendere un argomento del tipo di classe base ma del tipo di classe derivata.

class Derived: public Base { 
public: 
    virtual void seriousMethod(const Derived &arg) { /* ... */ } 
} 

Come posso realizzare questo? Dovrei specificare la classe di base (ad esempio Base<Derived>) oppure esiste una soluzione più pulita?

+0

Più precisamente - qual è la motivazione per farlo? –

+0

"La classe derivata dovrebbe tuttavia non prendere un argomento del tipo di classe base ma del tipo di classe derivata" - qual è il punto di avere allora i metodi virtuali? – berak

+0

@EdHeal Per essere specifico, una classe di nodo generico di ricerca A-Star che deve essere specificata dalle implementazioni derivate. – Appleshell

risposta

13

Non è possibile farlo direttamente. Pensare a questo caso:

Base b; 
Derived d; 
Base& d_ref = d; 
d_ref.seriousMethod(b); // What happens here? 

Al momento della compilazione, la variabile d_ref ha tipo statico Base, quindi secondo la definizione di Base, dovrebbe essere in grado di prendere b come parametro seriousMethod.

Ma in fase di esecuzione, il tipo dinamico di d_ref è Derived, quindi secondo la definizione di Derived, non può prendere b come parametro seriousMethod. Non è possibile convertire in Dervied poiché potrebbe essere un oggetto dritto Base (se Base non è astratto) oppure potrebbe essere un'altra classe derivata da Base che non è la stessa di Derived.

Lei ha ragione nel ritenere che l'unico vero modo per andare su questo è il motivo template curiosamente ricorrenti, vale a dire di template Base e la definizione Dervied come:

class Derived : public Base<Derived> { ... } 

Questo elimina il problema illustrato sopra, perché ogni il tipo derivato da Base<T> avrà una classe base distinta e non sarà correlato tra loro per via ereditaria.

Problemi correlati