Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Ада и другие языки _ Builder 6.0

Автор: Fanat 23.01.2008 1:09

Как перегрузить opertor+ для итератора list<MyClass>::iterator?..
То есть хочу чтобы работал следующий код


list<ILXListItem>::iterator it;
it = it + 5;


Сделать перегрузку тривиально, но где это записать и как етим правильно пользоваться?..

Автор: volvo 23.01.2008 1:38

Ну, ладно еще перегрузка операции для итератора, но почему list? У него же нет рандомного доступа... У vector-а есть... Вот смотри:

// Ну, перегрузка тривиальна - сам говоришь...
list<int>::iterator& operator += (list<int>::iterator &it, int value)
{
for(int i = 0; i < value; i++) ++it;
return it;
}

void __fastcall TForm1::Button2Click(TObject *Sender)
{
// Заполнили список для теста
list<int> myList;
for(int i = 0; i < 60; ++i) {
myList.push_back(i);
}

// А теперь - внимание: вот так сделать не получится !!!
// именно по причине отсутствия рандомного доступа
/*
for(list<int>::iterator it = myList.begin();
it < myList.end(); it += 5) {
// ...
}
*/

// вот __бредовый__ пример, показывающий, что перегрузка работает...
list<int>::iterator it = myList.begin();
for(int i = 0; i < 5; i++) {
Memo2->Lines->Add(IntToStr(*it));
it += 5;
}
}

Все-таки тебе либо не нужен list (точнее, нужен НЕ list), либо не надо перегружать подобным образом его итератор...

Автор: Fanat 23.01.2008 1:53

Мне нужно реализовать класс-обёртку для листа...и среди функций этого класса есть вставка элемента в задданое место и удаление элемента с заданного места...и это место задаётся индексом...а для этого мне кажется необходимо сдвинуть итератор на заданный индекс...Может я в чем то ошибаюсь?..или это можно сделать легче?..

Автор: volvo 23.01.2008 3:17

Тогда тебе проще будет сделать обычный

...
public:
void erase_element(int index) {
list<int>::iterator it = begin();
for(; index; --index) ++it;
erase(it);
}
...

(тестировалось на том же списке целых), не перегружая операторы сложения для итераторов...

Автор: Fanat 23.01.2008 3:23

Цитата(volvo @ 22.01.2008 23:17) *

Тогда тебе проще будет сделать обычный
...
public:
void erase_element(int index) {
list<int>::iterator it = begin();
for(; index; --index) ++it;
erase(it);
}
...

(тестировалось на том же списке целых), не перегружая операторы сложения для итераторов...


Ну да...я тоже подобное писал...но потом вспомнил что желательно выделять одинаковые куски кода...ведь сдвиг итератора понадобится не только в этой функции...ну да ладно вроде таких всего 2...

Добавлено через 4 мин.
Кстати при написании обёртки мой класс должен содержать внутри себя list?..

Автор: volvo 23.01.2008 3:38

smile.gif
Так лучше:

class TMyList: public list<int>
{
// ...
friend
TMyList::iterator&
operator + (TMyList::iterator &it, int index) {
for(; index; --index) ++it;
return it;
}

public:
void erase_element(int index) {
list<int>::iterator it = begin();
erase(it + index);
}
// ...
};

?

Автор: Fanat 23.01.2008 3:44

Мне кажется так лучше... smile.gif good.gif
(Значит класс должен наследоваться от list?..

Автор: volvo 23.01.2008 4:01

В принципе - да, ты же делаешь обертку, то есть сохраняешь функциональность List-а и добавляешь свое, значит твой новый класс является некоторым видом списка, так? Это реализуется наследованием...

Автор: Fanat 23.01.2008 4:12

Цитата(volvo @ 23.01.2008 0:01) *

В принципе - да, ты же делаешь обертку, то есть сохраняешь функциональность List-а и добавляешь свое, значит твой новый класс является некоторым видом списка, так? Это реализуется наследованием...


В задании даны функции вида добавить элемент в конец, очистить, и дан список операций над списком...
наверно имеется ввиду всё таки не сохранять всю функциональность list...ведь это можно добиться и агрегированием мне кажется...

И ещё

...
friend
TMyList::iterator& //А что означает здесь &?
operator + (TMyList::iterator &it, int index) {
for(; index; --index) ++it;
return it;
...





Автор: volvo 23.01.2008 4:24

Цитата
ведь это можно добиться и агрегированием мне кажется
А какая разница, дан тебе список операций или нет? Ну, сделаешь ты агрегированием, и что изменится? Разве что запретишь обращаться извне к тому или иному методу... Ну, как знаешь - тебе виднее, задание у тебя все-таки smile.gif

Цитата
// А что означает здесь &?
То есть, что означает & внутри скобок у тебя вопроса не возникло, а снаружи - непонятно? На самом деле - в обоих местах это означает одно и то же, возвращается ссылка на итератор, а не сам итератор.

Автор: Fanat 23.01.2008 4:32

Цитата(volvo @ 23.01.2008 0:24) *

То есть, что означает & внутри скобок у тебя вопроса не возникло, а снаружи - непонятно? На самом деле - в обоих местах это означает одно и то же, возвращается ссылка на итератор, а не сам итератор.


Ну снаружи достаточно сложно понять где класс а где тип возвращаемого значения...?
Вот в этой конструкции

list<ILXListItem*>::iterator&



Добавлено через 3 мин.
Цитата(Fanat @ 23.01.2008 0:32) *

Ну снаружи достаточно сложно понять где класс а где тип возвращаемого значения...?
Вот в этой конструкции

list<ILXListItem*>::iterator&




Всё понял...тут просто обьявляется дружественная функция...Спасибо...

Автор: volvo 23.01.2008 4:40

Не понял... Что сложного? Ссылка на итератор шаблонного класса list, хранящего указатели на ILXListItem... Вас что, не учили правилу "право-лево" для разбора сложных конструкций? blink.gif

Автор: Fanat 23.01.2008 4:41

Цитата(volvo @ 23.01.2008 0:40) *

Вас что, не учили правилу "право-лево" для разбора сложных конструкций? blink.gif

Не учили... sad.gif

Добавлено через 16 мин.
Цитата(Fanat @ 23.01.2008 0:41) *

Не учили... sad.gif


Почитал..Очень интересно...буду знать...;)