2009-05-20 2 views
7

Я пытаюсь создать класс итератора в качестве члена класса для класса список, и я пытаюсь перегрузить оператор разыменования (*) для доступа к списку он, указывая на:Как перегрузить оператор косвенности? (C++)

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

где lstptr является указателем на список, current является указателем на класс узла, а класс node содержит элемент данных data типа T.

Итератор объявлен как это:

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

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

Я могу компилировать определение функции перегруженного оператора * отлично, но когда я пытаюсь сделать что-то вроде:

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) 

Погрешность Я получаю сообщение < 1> что я использую незаконную косвенность, и < 2> что он не может преобразовать из списка :: iterator в int. Обе ошибки встречаются на четырнадцатой строке.

Кто-нибудь знает, что я делаю неправильно, и как я могу правильно перегрузить оператора косвенности?

NB: Если вам нужно увидеть больше кода, скажите мне, какая часть, потому что я не хочу размещать весь код здесь, потому что он имеет 205 строк, а 204 из этих строк не (я думаю) есть ошибки.

+0

Возможно, вы имели в виду "list :: iterator IT;" - это должен быть «список :: iterator IT;», правильно? – leander

+0

@leander: да, его список в действительном коде, я просто испортил ввод его в моем примере. – 2009-05-20 23:16:05

ответ

12

Вы перегрузили оператор умножения. Возьмите параметр, чтобы сделать его оператором косвенности.

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

Вы также должны иметь это вернуть ссылку, если вы хотите код, как *IT = 3; для компиляции.

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

Это не оператор умножения! Но вы верны о возврате справки. – Zifre

+4

Он должен написать оператор * как свободную функцию, поскольку он является оператором косвенности. Как было написано OP, это оператор умножения.Я тоже не обратил на это внимания, полностью игнорируя тот факт, что он, по-видимому, объявлен как член :) –

+0

поэтому return «& ((this-> lstptr) -> current) -> data"? – 2009-05-20 23:36:32

5

У вас здесь две проблемы; во-первых, вы случайно перегрузили оператор умножения, а не оператор разыменования; во-вторых, вы не вернули ссылочный тип.

Первая проблема возникает из-за количества параметров. Каждая нестатическая функция-член класса имеет дополнительный «скрытый» параметр: this. this - это, конечно, указатель на объект, на который вызывается функция. В результате вы фактически объявили версию оператора с двумя параметрами. Удалив второй параметр итератора и работая на this, вы будете перегружать унарный *, а не бинарный.

Вторая проблема относится к второму типу возврата; вы возвращаете копию оригинальному объекту, а не самому оригинальному объекту. Объявите возвращаемый тип как T&, чтобы вернуть ссылку.

+0

+1. Что касается типа возвращаемого значения, то он может * предпочтительнее просто возвращать копию, как это делает OP, если базовый тип является типом небольшого значения, и он не предназначен для назначения, но это был бы необычный случай. Предпочитаю ref, как предлагает coppro. –

Смежные вопросы