Страниц: [1]
  Печать  
Автор Тема: Как хранить объекты разных классов в одном списке  (Прочитано 6473 раз)
Fregl
Sr. Member
****
Offline Offline

Сообщений: 396


Просмотр профиля
« : Ноября 17, 2008, 09:56:33 pm »

Столкнулся с такой проблемой. Необходимо хранить объекты разных классов в одном списке.
В делфи это все довольно легко и прозрачно.
Т.е. к примеру есть такая иерархия классов
CShape (абстрактный)
CBox1,CBox2,CBox3,CBoxN - наследуемые классы от CShape
CBox1_1,CBox1_2 - наследуемые от CBox1... ну и в том же духе..
в делфи добавления объекта в список выглядит так
List.Add(TObject(CBox1Obj));
List.Add(TObject(CBox1_2Obj));
и т.д.

А вот теперь не могу понять, как мне такую же вещь реализовать в с++.
К примеру я сделал класс двусвязного списка, который в качестве ячейки данных хранит указатель (*void).

теперь есть несколько созданных объектов от разных классов, которые унаследованны от одного и того же CShape...
как мне их добавить/считать корректно в список.
у меня ничего путёвого не получается, делаю так

cbox1 = new CBox1;
list->Add((void*)cbox1);
cbox1_1 = new CBox1_1;
list->Add((void*)cbox1_1);
и т.д.

теперь когда мне надо изъять эти объекты, делаю так

CShape * obj;
list->GetItem(index,obj);
GetItem(int index, void * data);//прототип

впрочем
void * p;
CShape * obj;
list->GetItem(index,p);
obj = (CShape*)p;

результат один и тот же, все значения в полях объекта портятся, выяснить ссылка на какой класс не могу,
typeid(obj).name = говорит что это указатель на класс Shape...а мне надо получить указатель на объект класса, который я добавлял ранее в список...
помогите пожалуста, как корректно все это сделать...
Записан
lastcross
Full Member
***
Offline Offline

Сообщений: 237


Просмотр профиля
« Ответ #1 : Ноября 18, 2008, 01:29:25 pm »

Честное слов - все что вы делаете жесть какая-то. Использовать С++ и приводить указатели к void *?? Почитайте что-нить про полиморфизм и наследование. Потом почитайте  - патерны
Посути (в самом тривиальном случае) Вам в списке нужно хранить указатели на виртуальный базовый класс. И эти указатели кастовать к конкретным типам (то-ли посредстом dynamic_cast, typeid .. и тд - что не всегда хорошо, или организовать все это  каким либо патерном - это уж зависит от выбранной архитиктуры всего проекта)
Записан
Fregl
Sr. Member
****
Offline Offline

Сообщений: 396


Просмотр профиля
« Ответ #2 : Ноября 18, 2008, 02:18:48 pm »

да я не спорю, жесть еще та...
хз, может сделать какой то абстарктный пустой класс типа CObject в котором нет ничего вообще, а потом от него наследовать все классы, а в качестве ячейки данных ноды списка уже использовать (CObject*)?...
Не пинайте ногами сильно, просто не так легко перейти сразу с делфей на с++.
Записан
Fregl
Sr. Member
****
Offline Offline

Сообщений: 396


Просмотр профиля
« Ответ #3 : Ноября 18, 2008, 06:53:22 pm »

вобщем решил сделать так,
объявил пустой класс CObject с виртуальным деструктором,
и ноды хранят ссылку на этот тип.
и вот столкнулся с такой ошибкой

есть функция, которая возвращает значение элемента по индексу
void * CList::GetItem(USHORT index,CObject * Data)
{
... обход списка до нужного элемента
...а теперь его надо возвратить в Data
Data = found_node->data;//<-тут хранится указатель на объект
}

Казалось бы все должно работать, но при таком вызове:
CObject * p = NULL;
list->GetItem(0,p);
в p ничего не записывается. Отладчиком прогнал, в самой процедуре в аргумент функции Data значение записывается корректно, но почему то в передаваемый параметр p ничего не пишется, в чем я ошибся?
Записан
Evgeniy
Jr. Member
**
Offline Offline

Сообщений: 73


Просмотр профиля
« Ответ #4 : Ноября 18, 2008, 07:28:11 pm »

Fregl
list->GetItem(0,p);
в p ничего не записывается. Отладчиком прогнал, в самой процедуре в аргумент функции Data значение записывается корректно, но почему то в передаваемый параметр p ничего не пишется, в чем я ошибся?

Ошибка здесь: надо передать ссылку на указатель

list->GetItem(0,&p);

, тогда в указатель попадет то что вы пытаетесь туда записать
Записан
lastcross
Full Member
***
Offline Offline

Сообщений: 237


Просмотр профиля
« Ответ #5 : Ноября 18, 2008, 09:03:02 pm »

Интересно - а что собственно делает этот класс CList? Это типа врапера VCL? И также интересно зачем городить некий класс CList когда есть подобные уже std::list, vector, map  итд. Либо название класса неудачное, либо я не понимаю
Записан
Страниц: [1]
  Печать  
 
Перейти в: