2009-05-20 5 views
7

Je suis en train de créer une classe iterator comme classe membre pour une classe de liste, et essaie de surcharger l'opérateur indirection (*) pour accéder à la liste, il pointe vers:Comment surcharger l'opérateur d'indirection? (C++)

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

lstptr est un pointeur vers une liste, current est un pointeur vers une classe de noeud, et la classe de noeud contient l'élément de données de type data de T.

Iterator est déclarée comme ceci:

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

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

Je suis en mesure de compiler la définition de la fonction de l'opérateur surchargé * bien, mais lorsque je tente de faire quelque chose comme:

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) 

L'erreur Je reçois dit < 1> que j'utilise une indirection illégale, et < 2> qu'il ne peut pas convertir de list :: iterator en int. Les deux erreurs se produisent sur la ligne quatorze.

Quelqu'un sait-il ce que je fais mal et comment je peux surcharger correctement l'opérateur indirection? NB: Si vous avez besoin de voir plus de code, dites-moi quelle partie, parce que je ne veux pas mettre tout le code ici parce que ce n'est pas 205 lignes, et 204 de ces lignes ne le font pas (je pense) avoir des erreurs.

+0

Vouliez-vous saisir "liste :: iterator IT;" - il devrait être "liste :: ITerator IT;", non? – leander

+0

@leander: oui, sa liste dans le code actuel, j'ai juste foiré en tapant dans mon exemple. –

Répondre

12

Vous surchargées l'opérateur se multiplient. Sortez le paramètre pour en faire un opérateur d'indirection.

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

Vous devez également avoir une référence retourner si vous voulez code comme *IT = 3; pour compiler.

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

Ce n'est pas l'opérateur de multiplication! Mais vous avez raison de retourner une référence. – Zifre

+4

Il devrait écrire l'opérateur * comme fonction libre pour être l'opérateur d'indirection. Comme il a été écrit par l'OP, c'est l'opérateur de multiplication.Je l'ai en fait négligé aussi, ignorant totalement le fait qu'il soit apparemment déclaré comme membre :) –

+0

alors retour "& ((this-> lstptr) -> current) -> data"? –

5

Vous avez deux problèmes ici; le premier est que vous avez accidentellement surchargé l'opérateur de multiplication et non l'opérateur de déréférencement; la seconde est que vous n'avez pas retourné un type de référence.

La première question vient à la suite du nombre de paramètres. Chaque fonction membre non statique d'une classe a un paramètre "caché" supplémentaire: this. this est, bien sûr, le pointeur vers l'objet sur lequel la fonction est invoquée. En conséquence, vous avez effectivement déclaré une version de l'opérateur prenant deux paramètres. En supprimant le deuxième paramètre de l'itérateur et en opérant sur this, vous surchargerez l'unaire * et non le binaire.

La seconde question est mineure de type de retour; vous renvoyez une copie à l'objet original et non à l'objet original lui-même. Déclarez le type de retour comme T& pour renvoyer une référence.

+0

+1. En ce qui concerne le type de retour, il peut être préférable de renvoyer simplement une copie comme le fait le PO si le type sous-jacent est un petit type de valeur et non destiné à être assignable - mais ce serait un cas inhabituel. Préférez un ref comme le suggère coppro. –

Questions connexes