2009-05-20 17 views
7

Estoy tratando de crear una clase de iterador como una clase miembro de una clase de lista, y estoy tratando de sobrecargar el operador de indirección (*) para acceder a la lista que está señalando:¿Cómo sobrecargar el operador de indirección? (C++)

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

donde lstptr es un puntero a una lista, current es un puntero a una clase de nodo, y la clase de nodo contiene el miembro de datos data del tipo T.

iterador se declara así:

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

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

soy capaz de compilar la definición de la función del operador sobrecargado * bien, pero cuando trato de hacer algo como:

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) 

El error Me sale dice < 1> que estoy usando una indirección ilegal, y < 2> que no puede convertir de list :: iterator a int. Ambos errores ocurren en la línea catorce.

¿Alguien sabe lo que estoy haciendo mal y cómo puedo sobrecargar el operador de direccionamiento indirecto correctamente?

NB: Si necesita ver más código, dígame qué parte, porque no quiero poner todo el código aquí porque tiene 205 líneas, y 204 de esas líneas no (creo) tiene algún error

+0

¿Quisiste escribir "list :: iterator IT;" - debería ser "list :: iterator IT;", ¿verdad? – leander

+0

@leander: sí, su lista en el código actual, me equivoqué tipeando en mi ejemplo. –

Respuesta

12

Sobrecargó el operador de multiplicación. Elimine el parámetro para convertirlo en un operador indirecto.

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

También debe tener que devolver una referencia si quieres un código como *IT = 3; para compilar.

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

¡No es el operador de multiplicar! Pero tienes razón al devolver una referencia. – Zifre

+4

Debe escribir el operador * como una función gratuita porque es el operador indirecto. Como fue escrito por el OP, es el operador de multiplicación.En realidad, también lo pasé por alto, ignorando por completo el hecho de que aparentemente está declarado como miembro :) –

+0

, por lo que devuelve "& ((this-> lstptr) -> current) -> data"? –

5

Tiene dos problemas aquí; la primera es que accidentalmente has sobrecargado al operador de multiplicación y no al operador de desreferenciación; el segundo es que no ha devuelto un tipo de referencia.

El primer problema se produce como resultado de la cantidad de parámetros. Cada función miembro no estática de una clase tiene un parámetro "oculto" adicional: this. this es, por supuesto, el puntero al objeto sobre el que se invoca la función. Como resultado, ha declarado una versión del operador que toma dos parámetros. Al eliminar el segundo parámetro del iterador y operar en this, se sobrecargará el * único y no el binario.

El segundo problema es uno menor de tipo de devolución; está devolviendo una copia al objeto original y no al objeto original en sí. Declare el tipo de devolución como T& para devolver una referencia.

+0

+1. Con respecto al tipo de devolución, * puede * ser preferible simplemente devolver una copia como lo está haciendo OP si el tipo subyacente es un tipo de valor pequeño y no se pretende que sea asignable, pero sería un caso inusual. Prefiere una referencia, como sugiere el acuerdo. –

Cuestiones relacionadas