2013-06-17 8 views
10

Mam klasy Foo który jest w drzewiastej strukturze własny odsyłania (minimalnie):Czy powinienem const_cast "to", gdy metoda akceptuje tylko 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; 
} 

Linia return children.indexOf(child) oczekuje const T &value być przekazywane zgodnie z QList docs, ten postanawia Foo *const &value dla mojego scenariusza.

Aby moim getPosition() metody zadzwonić własną indexOf() metody jest to wymagane, aby mieć podpis const Foo *child na minimum w celu przekazania this z metody const. (Ponieważ jest to const Foo *const).

Mój kod nie zostanie skompilowany, ponieważ jako const Foo *const child nie można przesłać do Foo *const child dla QList::indexOf. Żadna z moich metod nie modyfikuje stanu obiektu, więc powinny one być stałe (tj. Nie chcę, aby nie kosztować getPosition, aby otrzymać niestanowiący this).

Pytanie brzmi, jak przejść od this w kontekście const (const Foo *const) do tego, czego wymaga QList::indexOf. Czy powinienem rzucać const this wewnątrz getPosition, ponieważ wiem, że moje indexOf (i kolejne wywołania) nie będą go mutować?

Czy jest coś jeszcze, co powinienem był zrobić? Być może mój projekt jest wadliwy.

+4

Czy prawdziwy problem polega na tym, że 'QList :: indexOf' nie jest metodą' const' i powinno być? – David

+1

Nie sądzę, że jest coś, co mógłbyś zrobić lepiej. Jeśli cokolwiek, projekt 'QList' może zostać ulepszony, aby umożliwić argumentowi wyszukiwania cokolwiek, co może być równe w porównaniu do jego typu elementu. Poszukiwanie "Foo const *" nie stanowiłoby problemu. Ale zakładam, że nie jesteś projektantem 'QList'. – celtschk

+3

@Dave 'QList :: indexOf' jest metodą const. http://qt-project.org/doc/qt-5.0/qtcore/qlist.html#indexOf –

Odpowiedz

5

myślę, że jest to całkowicie uzasadnione przypadki użycia dla const_cast, jednak nie jest to this trzeba const_cast, ale child. W tym przypadku, QList::indexOf oczekuje stałego wskaźnika na Foo (Foo* const), ale child jest stałym wskaźnikiem do stałej Foo (const Foo* const). Nie istnieje żadna niejawna konwersja z Foo* const do const Foo* const, ponieważ usunie to const-ness z wskazywanej wartości.

Tak, aby naprawić swój kod chciałbym zmienić linię do

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

Wiesz QList::indexOf nie zamierza zmieniać cokolwiek child punkty do, więc to nie będzie produkować niezdefiniowanej zachowanie. Dodałbym jednak komentarz wyjaśniający, dlaczego konieczne jest const_cast.

Powiązane problemy