2009-05-20 17 views
7

Próbuję utworzyć klasę iterator jako członek klasy do klasy listy i staram się przeciążać operatora zadnie (*), aby uzyskać dostęp do listy to wskazując na:Jak przeciążyć operator indeksu? (C++)

template<class T> 
T list<T>::iterator::operator*(iterator& iter) 
{ 
    return ((iter.lstptr)->current)->data; 
} 

gdzie lstptr jest wskaźnikiem do listy, current jest wskaźnikiem do klasy węzła, a klasa węzła zawiera element danych data typu T.

Iterator jest zadeklarowana następująco:

template<class T> 
class list 
{ 
public: 
class iterator; 
}; 

template<class T> 
class list<T>::iterator 
{ 
//stuff 
}; 

jestem w stanie skompilować definicja funkcji przeciążonego operatora * w porządku, ale gdy próbuję zrobić coś takiego:

list<int> lst1; 
lst1.add(6); 
list<int>::iterator IT; 
IT = lst1; 
//everything above this point compiles fine 
int a = *IT; //error here (line fourteen) 

błędu Otrzymuję komunikat: < 1> że używam niedozwolonego niedozwolenia, a < 2> że nie może konwertować z listy :: iterator na int. Oba błędy występują w linii czternastej.

Czy ktoś wie, co robię źle i jak mogę poprawnie przeciążać operatora indeksu?

NB: Jeśli potrzebujesz więcej kodu, powiedz mi, która część, ponieważ nie chcę wstawić tutaj całego kodu, ponieważ jest to 205 linii, a 204 z tych linii nie (myślę) Mam jakiekolwiek błędy.

+0

Czy chcesz wpisać "list :: iterator IT;" - powinno być "lista :: iterator IT;", prawda? – leander

+0

@leander: tak, jego lista w rzeczywistym kodzie, właśnie pomieszałem wpisanie tego w moim przykładzie. –

Odpowiedz

12

Przeciążono operatora mnożenia. Wyjmij parametr, aby był operatorem w kierunku pośrednim.

template<class T> 
T list<T>::iterator::operator*() 
{ 
    return ((this->lstptr)->current)->data; 
} 

Należy również mieć to zwrócić odwołanie jeśli chcesz kod jak *IT = 3; skompilować.

template<class T> 
T& list<T>::iterator::operator*() 
{ 
    return ((this->lstptr)->current)->data; 
} 
+1

To nie jest operator multiplikuj! Ale masz rację, zwracając referencję. – Zifre

+4

Powinieneś napisać operator * jako darmową funkcję, ponieważ jest operatorem niezależnym. Jak napisała OP, jest to operator mnożenia.Właściwie to przeoczyłem, całkowicie ignorując fakt, że najwyraźniej został zadeklarowany jako członek :) –

+0

, więc zwróć "& ((this-> lstptr) -> current) -> data"? –

5

Masz tu dwa problemy; pierwszy to przypadkowe przeciążenie operatora mnożenia, a nie operatora dereferencji; po drugie, nie zwróciłeś typu referencyjnego.

Pierwszy problem pojawia się w wyniku liczby parametrów. Każda niestatyczna funkcja członkowska klasy ma dodatkowy "ukryty" parametr: this. this jest oczywiście wskaźnikiem do obiektu, na którym wywoływana jest funkcja. W rezultacie faktycznie zadeklarowałeś wersję operatora, biorąc dwa parametry. Po usunięciu drugiego parametru iteratora i uruchomieniu na wartości this nastąpi przeciążenie unarnego *, a nie binarnego.

Drugi problem to niewielki typ zwrotu; zwracasz kopię do oryginalnego obiektu, a nie do oryginalnego obiektu. Zadeklaruj typ zwrotu jako T&, aby zwrócić referencję.

+0

+1. Jeśli chodzi o typ zwrotu, * może * być lepszym rozwiązaniem niż tylko zwrócenie kopii, jak działa OP, jeśli typ bazowy jest typem małej wartości i nie jest przeznaczony do przypisania - ale byłby to nietypowy przypadek. Wolisz ref, jak sugeruje coppro. –