Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.80
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
#1

Метод класса возвращающий итератор - C++

02.10.2011, 16:41. Просмотров 2054. Ответов 32
Метки нет (Все метки)

Не могу заставить метод класса возвращать итератор, помогите понять почему компилятор не разрешает это сделать:

Класс (методы возвращающие итераторы в самом низу)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Students
{
    friend class StudentsIterator;
    struct ListItem
    {
        string fullname;
        string group;
        int year;
        int average;
        ListItem *Next;
    };
 
    ListItem *Head;
    ListItem *Tail;
    ListItem *Current; //указатель на текущий элемент
    int count; // всего элементов
 
public:
 
    Students(): Head(0), Tail(0), Current(0), count(0) {}
 
    Students(string data, int y, int a, string g)
    {
        Head=Tail=new ListItem(data,y,a,g);
        Current=0;
        count=1;
    }
 
    ~Students(){this->deleteAll();}
 
    //методы для итераторов
    StudentsIterator* begin(){return Head;} //  cannot convert `Students::ListItem*' to `StudentsIterator*' in return
    StudentsIterator* end(){return NULL;} // ВСЁ ОК, КОМПИЛЯТОР НЕ РУГАЕТСЯ
};
Класс-итератор для него ,как видите есть перегруженный конструктор принимающий ListItem*:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class StudentsIterator
{
private:
    Students::ListItem* current;
 
public:
 
    StudentsIterator() {current=0;}
 
    StudentsIterator(const Students &right)
    {
        *this=right;
    }
 
    StudentsIterator(Students::ListItem* right)
    {
        *this=right;
    }
 
 
    StudentsIterator* operator=(Students &right)
    {
        current=right.Current;
        return this;
    }
 
    //для указателей на элемент, например на начало или конец списка
    StudentsIterator operator=(Students::ListItem* right)
    {
        current=right;
        return *this;
    }
 
    StudentsIterator* operator*()
    {
        return this;
    }
 
    operator bool()
    {
        return current!=0;
    }
 
};
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.10.2011, 16:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Метод класса возвращающий итератор (C++):

Создать для класса виртуальный метод, возвращающий уникальный идентификатор класса - C++
В курсаче по ООП сказано создать для класса виртуальный метод,возвращающий уникальный идентификатор класса. Вопрос в том, что это такое?

Шаблон класса двусвязного списка, метод, возвращающий указатель - C++
Пишу шаблон класса двусвязного списка. Всё в хедере. В классе присутствует структура item. Пытаюсь написать метод, возвращающий указатель...

Итератор класса vector - C++
Доброго времени суток. Попалась задача, в которой нужно определить итератор с проверкой выхода за пределы допустимого диапазона для...

Метод, возвращающий данные по имеющемуся ключу массива MAP - C++
Исходный код: #include <string> #include "map.h" class Recipe{ protected: AnsiString name_recipe; //название...

Итератор для класса с массивом - C++
Добрый день! Есть небольшая задачка.. необходимо написать класс для готовых комманд код for (Ada::Iterator adaIter =...

Итератор внутри шаблонного класса - C++
пытаюсь создать свой контейнер (на основе std::map) добавлять в него пару данных разных типов, а потом считывать вторую часть пары...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
LosAngeles
Заблокирован
02.10.2011, 16:49 #2
StudentsIterator begin(){ return Head; }
то что у тебя указатель на итератор возвращается я так понимаю ошибка
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
02.10.2011, 16:53 #3
вы возвращает ListItem* (Head), хотя объявляете будто это StudentsIterator, что предлагаете компилятору делать?
второй вариант работает, так как NULL можно приводить к указателям любого типа
0
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
02.10.2011, 17:01  [ТС] #4
LosAngeles, угу, а я какраз хочу чтобы функции класса begin() и end() возвращала итератор - это будет удобно для сортировки, печати и т.д. Я конечно могу сделать чтобы эта функция возвращала не итератор:
C++
1
2
        ListItem* begin(){return Head;} // Так нормально
        ListItem* end(){return NULL;} // компилируется
А потом в main делать так:
C++
1
2
3
Students obj;
StudentsIterator ite=obj.begin(); //Тоже всё ок, ite указывает на начало списка студентов
StudentsIterator ite_end=obj.end();//ite_end установлен в нуль (указывает на элемент ПОСЛЕ односвязного списка, те нуль)
Но это утомительно да и выглядит неуклюже когда я при печати списка создаю два новых итератора, печатаю список через них и больше их не использую, преподаватель наверняка прицепится насчёт этого.

Добавлено через 1 минуту
Цитата Сообщение от alex_x_x Посмотреть сообщение
вы возвращает ListItem* (Head), хотя объявляете будто это StudentsIterator, что предлагаете компилятору делать?
Воспользоваться конструктором копирования класса StudentsIterator перегруженого для получения ListItem* и вернуть мне этот итератор. Но это хочу я, как тогда по другому это сделать если компилятор так делать не хочет?
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
02.10.2011, 17:08 #5
C++
1
StudentsIterator begin(){return StudentsIterator(Head);}
не ?
1
LosAngeles
Заблокирован
02.10.2011, 17:13 #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class Students
{
    friend class StudentsIterator;
    struct ListItem
    {
        string fullname;
        string group;
        int year;
        int average;
        ListItem *Next;
    };
 
    ListItem *Head;
    ListItem *Tail;
    ListItem *Current; //указатель на текущий элемент
    int count; // всего элементов
 
public:
 
    class StudentsIterator
    {
    private:
        Students::ListItem* current;
 
    public:
 
        StudentsIterator() {current=0;}
 
        StudentsIterator(const Students &right)
        {
            *this=right;
        }
 
        StudentsIterator(Students::ListItem* right)
        {
            *this=right;
        }
 
 
        StudentsIterator* operator=(Students &right)
        {
            current=right.Current;
            return this;
        }
 
        //для указателей на элемент, например на начало или конец списка
        StudentsIterator operator=(Students::ListItem* right)
        {
            current=right;
            return *this;
        }
 
        StudentsIterator* operator*()
        {
            return this;
        }
 
        operator bool()
        {
            return current!=0;
        }
 
    };
 
    Students(): Head(0), Tail(0), Current(0), count(0) {}
 
    Students(string data, int y, int a, string g)
    {
        //Head=Tail=new ListItem(data,y,a,g);
        Current=0;
        count=1;
    }
 
    ~Students(){}
 
    //методы для итераторов
    StudentsIterator begin(){return Head;} //  cannot convert `Students::ListItem*' to `StudentsIterator*' in return
    StudentsIterator end(){return NULL;} // ВСЁ ОК, КОМПИЛЯТОР НЕ РУГАЕТСЯ
};
1
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
02.10.2011, 17:18 #7
В варианте LosAngeles просто неявно вызовется конструктор StudentsIterator(Students::ListItem* right)
0
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
02.10.2011, 17:21  [ТС] #8
alex_x_x, не:
C++
1
2
3
In member function `StudentsIterator* Students::begin()':|
|80|error: invalid use of undefined type `struct StudentsIterator'|
|21|error: forward declaration of `struct StudentsIterator'|
Я так уже пробовал.
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
02.10.2011, 17:23 #9
Цитата Сообщение от alex_x_x Посмотреть сообщение
StudentsIterator begin(){return StudentsIterator(Head);}
Цитата Сообщение от Gepar Посмотреть сообщение
StudentsIterator* Students::begin()
чтото не сходится
0
LosAngeles
Заблокирован
02.10.2011, 17:23 #10
Цитата Сообщение от Gepar Посмотреть сообщение
Я так уже пробовал.
в моём варианте этой проблемы нет
0
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
02.10.2011, 17:37  [ТС] #11
Хотя нет, это я же написал что возвращаю указатель, а нужно просто возвращать StudentsIterator по версии alex_x_x, вот только вернуть получается просто StudentsIterator только если код class StudentsIterator находится внутри класса Students, иначе ругается, а код то у меня на самом деле большой ... как же его тогда подключить. Если перекидываю код класса-итератора в cpp файл, который компилирую совместно то компилятор ругается что не знает что такое ListItem , как сделать предварительное объявление тогда этой структуре ? (структура ListItem находится в классе Students).
LosAngeles, вообще чисто Ваш вариант тоже не работает (неявно не вызывается, опять же таки ругается почему-то, хотя должен и неявно вызываться как я изначально и планировал), но я не могу запихнуть код класса-итератора внутрь так как он большой, я ведь сюда запостил только то что касается проблемы чтобы не отпугивать и не запутывать Вас.

Добавлено через 8 минут
В общем у меня замкнутый круг: чтобы определить класс-итератор нужно чтобы был объявлен класс Студентов, а чтобы объявить методы begin/end класса Студенты нужно чтобы уже был объявлен итератор, как апофеоз всего этого:
сделав объявление в классе:
C++
1
2
    StudentsIterator begin();
    StudentsIterator end();
и потом сразу после определения класса-итератора внизу дописываю
C++
1
2
StudentsIterator Students:: begin(){return Head;}
StudentsIterator Students:: end(){return StudentsIterator(0);}
и получаю
Код
obj\Debug\main.o(.text+0x100)||In function `ZN8Students5beginEv':|
C:\c++\Projects\StudentsProject\Students.h|161|multiple definition of `Students::begin()'|
obj\Debug\students.o(.text+0x100):C:\c++\Projects\StudentsProject\Students.h|161|first defined here|
obj\Debug\main.o(.text+0x120)||In function `ZN8Students3endEv':|
C:\c++\Projects\StudentsProject\Students.h|162|multiple definition of `Students::end()'|
obj\Debug\students.o(.text+0x120):C:\c++\Projects\StudentsProject\Students.h|162|first defined here|
||=== Build finished: 4 errors, 0 warnings ===|
Те компилятор пишет что я определяя функцию переопределяю её (и первое и второе определение функции он пишет что это одна строка) О_о Всё, поздравьте меня, я запутался в ошибках компилятора окончательно.
0
LosAngeles
Заблокирован
02.10.2011, 17:40 #12
Цитата Сообщение от Gepar Посмотреть сообщение
но я не могу запихнуть код класса-итератора внутрь так как он большой
ctrl+copy - ctrl+paste и всё работает. И проблема циклических ссылок разрешена, а "большой код" как бы не является ни для кого проблемой
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
02.10.2011, 17:43 #13
у вас ошибка в повторном определении функции begin()
0
Gepar
1177 / 533 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
02.10.2011, 17:50  [ТС] #14
При попытках компилировать в VS я так понял из ошибок что строки в классе
C++
1
2
        StudentsIterator begin();
        StudentsIterator end();
оно воспринимает как объявление нового толи класса толи ещё чего-то, в общем как я понял мне нужно только как-то отделять класс-итератор в другой файл и компилировать вместе, посему нужно как-то обьявить существование структуры ListItem из класса Students - это должно быть решением всех моих проблем, но как это сделать?

Добавлено через 3 минуты
Цитата Сообщение от LosAngeles Посмотреть сообщение
ctrl+copy - ctrl+paste и всё работает. И проблема циклических ссылок разрешена, а "большой код" как бы не является ни для кого проблемой
Является, мой преподаватель любит "класивый код", для него это, как он выразился, "даставляет истинное наслаждение".

Цитата Сообщение от alex_x_x Посмотреть сообщение
у вас ошибка в повторном определении функции begin()
Где?
C++
1
2
StudentsIterator begin(); //обьявление в классе
StudentsIterator Students:: begin(){return Head;} //определение вне класса
объявление-определение, разве я где-то ошибся?
0
LosAngeles
Заблокирован
02.10.2011, 17:59 #15
Цитата Сообщение от Gepar Посмотреть сообщение
Является, мой преподаватель любит "класивый код", для него это, как он выразился, "даставляет истинное наслаждение".
где тут большой код то? глиста на две страницы это препод называет большим кодом? значит он некомпетентен, можно не обращать на него внимание
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.10.2011, 17:59
Привет! Вот еще темы с ответами:

итератор для шаблонного класса - C++
Всем солнца! Честно честно честно пересмотрел более 100 различных вариантов разных решений. НО.... :wall: есть список: ...

Итератор для класса-группы - C++
Доброго времени суток. Нужна помощь. Выполняя лабы по методичке вновь возникла проблема с пониманием логики автора. Необходимо передать в...

Как передать в метод класса Menu указатель на метод дочернего класса? - C++
Как передать в метод базового класса указатель на метод дочернего: class Menu() { protected: setCallback(*********); //...

Как вынести метод возвращающий шаблонный класс в из hpp в cpp? - C++
Есть код в заголовоном файле: template<class T,typename Ptr> class LINQ { private: Ptr begin; Ptr end; std::vector<T*>...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
02.10.2011, 17:59
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru