Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Создать список из классов


Автор: haword 21.10.2004, 07:41
Такая задача встала, может кто сталкивался с такой. Надо создать список содержащий различные классы, никак не могу придумать как это сделать :( Что то навроде этого:

class Pervyi
{
public:
string name;
string type;
}

class Vtoroi
{
public:
string name;
string type;
}

List.AddClass(Pervyi);
List.AddClass(Vtoroi);

как вот этот лист реализовать? Есть может какие стандартные функции для этого?


Автор: mr.DUDA 21.10.2004, 07:53
Добавляй в список указатели на объекты, а не сами объекты:
Код
class A {};
class B {};


class List
{
 void Add(void *object)
 {
      // ...
 }
}


А перед тем, как начинать изобретать свой велосипед... простите, список -- я бы посоветовал заглянуть в С++ FAQ, тема "Об STL простыми словами - Динамические массивы, списки и т.п.".

Автор: haword 21.10.2004, 12:56
втот то весь и прикол что при STL пишется примерно так:
class a {};
class b{};

vector<a> list
или
vector<b> list

а надо и а класс и b класс в один список добавлять, в том и проблема

Автор: maxim1000 21.10.2004, 13:10
тут несколько другой вопрос: создать список именно классов
здесь можно попробовать такой подход:
1. все классы должны наследоваться от одного
2. создается список не классов, а "фабрик"
под фабрикой класса здесь понимается функция, которая создает объект с параметрами по умолчанию

Автор: Mad 21.10.2004, 13:19
haword
Если ты просто накидаеш разные классы в обин список, то как ты потом их разбирать будеш :)
А если у класов есть чтото общее (например родительский класс) то просто делаеш список из родителей :)

Автор: chipset 21.10.2004, 13:23
Цитата(Mad @ 21.10.2004, 03:19)
Если ты просто накидаеш разные классы в обин список, то как ты потом их разбирать будеш

Можно реализовать на коленке RTTI, то есть встроить в базовый класс object имя типа..
Цитата(Mad @ 21.10.2004, 03:19)
А если у класов есть чтото общее (например родительский класс) то просто делаеш список из родителей 

Базовый object..

Автор: maxim1000 21.10.2004, 13:25
вообще, лучше бы чуть полнее описать задачу на уровень выше (т.е. зачем понадобился список классов), тогда помощь может оказаться более эффективной...

Автор: haword 22.10.2004, 08:12
Спасибо за ответы! Сделал так
Код

class Roditel
{
public:
string Proba;
};

class Child: public Roditel
{
public:
 string a;
};


typedef Roditel sz;

class ValueList
{
 vector<sz , allocator<sz> > lz;
public:
 ValueList()
 {
  lz.clear();
 }
 void AddValue(sz& Znach)
 {
   lz.insert(lz.begin(),Znach);
 };
 void GetValue(sz& Znach)
  {
   Znach = lz.at(0);
  };
};

int main(void)
{
Child a;
Child b;
ValueList vl;
a.a="ssss";
a.Proba="aaa";
vl.AddValue(a);
vl.GetValue(b);
cout << b.a << b.Proba << endl;
return 0;
};

выводит только b.Proba, b.a не сохраняется, забываются значения класса Child :( Выводятся значения только родительского класса :( Я в этом деле новичек, может что то напутал? Как мне сделать чтоб получить значения дочернего класса?

Автор: bel_nikita 22.10.2004, 10:51
не, не очень. лучше хранить поинтеры на объекты, а не сами объекты. потом проблеммы с конструктором копий начнуться

Автор: haword 22.10.2004, 11:50
Цитата(bel_nikita @ 22.10.2004, 10:51)
не, не очень. лучше хранить поинтеры на объекты, а не сами объекты. потом проблеммы с конструктором копий начнуться

как?

Автор: bel_nikita 22.10.2004, 12:21
Код
typedef Roditel* sz;


Код
vl.AddValue(&a);
vl.GetValue(&b);


Вроде так :)

Автор: haword 22.10.2004, 14:10
а если я потом классы а и b удаляю то в списке указатель этот класс тоже ведь летит так? а мне хранить их надо

Автор: bel_nikita 22.10.2004, 15:22
hawordага.
Если удаляешь объекты, то удаляй и поитеры на них из списка.
Ворочать укзателями намного эффективнее, нежели целыми объектами.

Цитата
вообще, лучше бы чуть полнее описать задачу на уровень выше (т.е. зачем понадобился список классов), тогда помощь может оказаться более эффективной...

я тож поддерживаю эту идею

Автор: Guest 23.10.2004, 20:50
Огромное спасибо за советы! Моя задача была такова!
1. Есть класс - папа.
2. У него есть некий набор виртуальных ф-ций (допустим, GetType)
3. Есть у него дети, каждый из которых как накрывает виртуальный ф-ции (например, реализует свой GetType), так и имеет свои

Задача - нужен класс - контейнер (типа std::Array), чтобы в него можно было запихивать любого из детей.

Я скланяюсь к использованию boost::any типа
std::vector< boost::any<Roditel> > v, думаю это наиболее правильное решение или нет? Хотя в принципе не хотелось бы лишнюю либу (тот же boost), если можно обойтись своими силами и STL

Автор: Mad 24.10.2004, 13:33
Не знаю что тут лучше std::vector или std::list, зависит от того, что ты дальше с этим списком делать будеш.
Цитата(Guest @ 23.10.2004, 20:50)
std::vector< boost::any<Roditel> > v,

непонятно зачем тебе тут boost::any<Roditel>
std::vector<Roditel> нормально работает :)

Автор: haword 25.10.2004, 17:50
потому что при передаче дочернего класса у меня пропадают параметры дочернего класса остаются только параметры родительского класса

Автор: Mad 25.10.2004, 18:07
haword
Да никуда они не пропадают. Если ты храниш сами обьекты то
((Child*)(&array[x]) дает тебе указатель на Child со всеми его свойствами :)

Автор: haword 25.10.2004, 18:16
Mad
Плизз! как мне сделать это в контексте моего класса напищи пожалуста! Я несильно хорошо в си++ разбираюсь!

Автор: Mad 25.10.2004, 18:23
haword
Код

class Parent
{
}

class Child : public Parent
{
   int m_ChildField;
}

typedef std::array<Parent> ParentArray;

void AnyFunction(void)
{
   ParentArray array;
   Child ch;
   
   array[0] = ch;

   ((Child*)(&array[0]))->m_ChildField = 0; // будет прекрасно работать

Автор: bel_nikita 25.10.2004, 21:34
Mad
Я конечно извиняюсь, но то, что ты написал в последнем примере полное не то :)
Цитата
std::array<Parent>
что такое array? наверное vector подразумевался :)
Цитата
array[0] = ch;
тоже не очень :)
Цитата
((Child*)(&array[0]))->m_ChildField = 0; // не будет прекрасно работать  :stena

Про точкую с запятой и virtual в деструкторе уже не буду упоминать :yasno

З.Ы.: только без обид :)
З.Ы.2: если будет время черкану простенький пример контейнер

Добавил: :rtfm
простенький примитив поясняющий что да как ( времени особо нет пояснить толково, завтра постараюсь )
Код
typedef std::vector<Parent*> CONTAINER;
CONTAINER  m_objContainer;                 // empty container!
m_objContainer.reserve(100);               // reservation memory
Child* pch = new Child();
m_objContainer[0] = pch;                   // 1st elem add to container
m_objContainer.push_back(new Child());     // 2nd elem add to container

Child child;                              
m_objContainer[3] = &child;                // 3rd elem add to container

m_objContainer[0]->m_Parent = 0xFFFF;
((Child*)m_objContainer[0])->m_ChildField = 0xEEEE;

...

// delete odject
for ( CONTAINER::iterator iter = m_objContainer.begin(); iter != m_objContainer.end(); ++iter  )
{
  delete *iter;
}

А! Еще не забудь virtual ~ Parent() ставить

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)