2009-05-20 6 views
7

Ich versuche, eine Iterator-Klasse als Mitglied-Klasse für eine Liste Klasse zu erstellen, und ich versuche, die Indirektionsoperator zu überlasten (*), um die Liste zuzugreifen es zeigt auf:Wie überladen Sie den Indirektionsoperator? (C++)

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

Dabei ist lstptr ein Zeiger auf eine Liste, current ist ein Zeiger auf eine Knotenklasse und die Knotenklasse enthält das Datenelement data vom Typ T.

Iterator wird wie folgt erklärt:

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

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

Ich bin in der Lage, die Funktion Definition des überladenen Operators * in Ordnung, zu kompilieren, aber wenn ich versuche, wie etwas zu tun:

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) 

Der Fehler Ich bekomme sagt < 1>, dass ich eine illegale Umleitung, und < 2>, dass es nicht von list :: iterator zu int konvertieren kann. Beide Fehler treten in Zeile 14 auf.

Weiß jemand, was ich falsch mache und wie ich den Indirektionsoperator richtig überladen kann?

NB: Wenn Sie mehr Code sehen wollen, sagen Sie mir, welcher Teil, weil ich nicht den ganzen Code hier hochlegen möchte, weil es 205 Zeilen und 204 dieser Zeilen nicht (glaube ich) habe irgendwelche Fehler.

+0

Meinen Sie "Typ list :: Iterator IT;" - Es sollte sein "Liste :: Iterator IT", oder? – leander

+0

@leander: ja, seine Liste im eigentlichen Code, habe ich gerade versäumt, es in meinem Beispiel zu tippen. –

Antwort

12

Sie haben den Multiplikationsoperator überlastet. Nehmen Sie den Parameter heraus, um ihn zu einem Indirektionsoperator zu machen.

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

Sie sollten es auch einen Verweis zurück, wenn Sie Code wie *IT = 3; wollen kompilieren.

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

Es ist nicht der Multiplikator! Aber Sie haben Recht, wenn Sie eine Referenz zurückgeben. – Zifre

+4

Er sollte den Operator * als freie Funktion schreiben, da er der Indirektionsoperator ist. Wie es vom OP geschrieben wurde, ist es der Multiplikationsoperator.Ich habe es auch übersehen und total ignoriert, dass es anscheinend als Mitglied deklariert wurde :) –

+0

also zurück "& ((this-> lstptr) -> current) -> data"? –

5

Sie haben hier zwei Probleme; der erste ist, dass Sie versehentlich den Multiplikationsoperator und nicht den Dereferenzierungsoperator überladen haben; Zum anderen haben Sie keinen Referenztyp zurückgegeben.

Das erste Problem ergibt sich aus der Anzahl der Parameter. Jede nicht statische Elementfunktion einer Klasse hat einen zusätzlichen "versteckten" Parameter: this. this ist natürlich der Zeiger auf das Objekt, auf dem die Funktion aufgerufen wird. Als Ergebnis haben Sie eine Version des Operators deklariert, die zwei Parameter verwendet. Indem Sie den zweiten Iterator-Parameter entfernen und unter this arbeiten, überlasten Sie den unären * und nicht den binären.

Das zweite Problem ist ein geringfügiger Rückgabetyp; Sie geben eine Kopie an das ursprüngliche Objekt und nicht das ursprüngliche Objekt selbst zurück. Deklarieren Sie den Rückgabetyp T&, um eine Referenz zurückzugeben.

+0

+1. In Bezug auf den Rückgabetyp * * * ist es möglicherweise vorzuziehen, nur eine Kopie zurückzugeben, wie es der OP tut, wenn der zugrunde liegende Typ ein kleiner Werttyp ist und nicht zuweisbar ist - aber das wäre ein ungewöhnlicher Fall. Bevorzugen Sie eine Referenz, wie Coppro es vorschlägt. –