2013-06-17 10 views
10

Ho una classe Foo che è in un self riferimento albero-come la struttura (in minima parte):Dovrei const_cast "questo" quando un metodo accetta solo Foo * const?

class Foo { 
    public: 
     // Gets this child's position relative to it's parent. 
     int getPosition() const { 
      return parent->indexOf(this); 
     } 

     int indexOf(const Foo *const child) const { 
      return children.indexOf(child); // this line causes an error. 
     } 
    private: 
     Foo *parent; 
     QList<Foo *> children; 
} 

La linea return children.indexOf(child) aspetta const T &value da passare come da QList docs, questo decide di Foo *const &value per il mio scenario.

Affinché il mio metodo getPosition() di chiamare il mio proprio metodo indexOf() è richiesto di avere una firma di const Foo *child al minimo per passare da un metodo this const. (Poiché questo è const Foo *const).

Il mio codice non verrà compilato tuttavia come const Foo *const child non può essere trasmesso a Foo *const child per QList::indexOf. Nessuno dei miei metodi modifica lo stato dell'oggetto in modo che debbano essere const (vale a dire non voglio rendere un costo non limitato getPosition per ricevere un numero non costante this).

Quindi la domanda è: come faccio ad andare da this in un contesto const (const Foo *const) a quello che QList::indexOf richiede. Dovrei essere const casting this all'interno di getPosition poiché so che il mio indexOf (e le chiamate successive) non lo muteranno?

C'è qualcos'altro che avrei dovuto fare? Forse il mio design è difettoso.

+4

Il vero problema è che 'QList :: indexOf' non è un metodo' const', e dovrebbe essere? – David

+1

Non penso che ci sia qualcosa che avresti potuto fare meglio. Se possibile, la progettazione di 'QList' potrebbe essere migliorata, per consentire come argomento di ricerca qualsiasi cosa che possa essere uguaglianza, rispetto al suo tipo di elemento. Quindi cercare 'Foo const *' non sarebbe un problema. Ma presumo che tu non sia il designer di 'QList'. – celtschk

+3

@Dave 'QList :: indexOf' è un metodo const. http://qt-project.org/doc/qt-5.0/qtcore/qlist.html#indexOf –

risposta

5

credo che questo sia un caso d'uso perfettamente ragionevole per const_cast, tuttavia non è this è necessario const_cast, ma child. In questo caso, QList::indexOf prevede un puntatore costante a (Foo* const) ma child è un puntatore costante a una costante Foo (const Foo* const). Non vi è alcuna conversione implicita da Foo* const a const Foo* const poiché ciò rimuoverebbe la costante dal valore puntato.

Così, per risolvere il tuo codice che avrebbe cambiato la linea di

return children.indexOf(const_cast<Foo*>(child)); 

Sai QList::indexOf non ha intenzione di modificare qualsiasi child punti a, quindi questo non produrrà un comportamento indefinito. Vorrei tuttavia aggiungere un commento che spieghi perché è necessario lo const_cast.

Problemi correlati