Russian Qt Forum

Qt => Общие вопросы => Тема начата: Elron от Апрель 09, 2010, 23:39



Название: Как потомков из базового класса "засунуть" в один список ?
Отправлено: Elron от Апрель 09, 2010, 23:39
    Допустим есть класс А, который порождает два разных класса Б и В, у которых есть свои/другие методы и переменные.. нужно эти потомки Б и В добавлять в один список(предпочтительно словарь QMap) и обращаться к ним..
    Есть альтернатива решения: создать новый класс(который будет в списке), в котором будут все эти предки класса А, но фактически будет использоваться только один из них.. но тогда будет выделяться неиспользуемая память!!
PS: давно не писал на С++


Название: Re: Как потомков из базового класса "засунуть" в один список ?
Отправлено: break от Апрель 09, 2010, 23:47
1) Вопрос по C++ а не Qt

2) вы у себя в теме сначала говорите что от класса А есть потомки Б и В 
Цитировать
класс А, который порождает два разных класса Б и В
а потом что
Цитировать
котором будут все эти предки класса А

Если все таки А базовый класс - то в QMap надо хранить указатели на него, и при необходимости кастить в соответствующего наследника.


Название: Re: Как потомков из базового класса "засунуть" в один список ?
Отправлено: Elron от Апрель 10, 2010, 00:00
Кажется Вы меня не так поняли: мне нужно именно классы Б и В "засунуть" в список.
Если все же поняли именно так, то как "кастить в соответствующего наследника" ? пример кода очень поможет))


Название: Re: Как потомков из базового класса "засунуть" в один список ?
Отправлено: break от Апрель 10, 2010, 00:34
засовывать надо указатель на экземпляры наследников как указатель на базового класса а не сами экземпляры наследников - если это наследники QObject то можно кастить через qobject_cast
иначе через static_cast и др. стандартные конструкции приведения типов C++ в зав. от ситуации ( dynamic_cast, reinterprep_cast и др. )


Название: Re: Как потомков из базового класса "засунуть" в один список ?
Отправлено: niXman от Апрель 10, 2010, 00:47
Elron, приведите пример кода, воспроизводящего ситуацию.


Название: Re: Как потомков из базового класса "засунуть" в один список ?
Отправлено: Elron от Апрель 10, 2010, 02:45
main.cpp
Код
C++ (Qt)
class A
{
public:
   void set(QString s) { str = s; }
   QString get() { return str; }
 
protected:
   QString str;
};
 
class B : public A
{
public:
   void set(QString s){ str = s; }
   void setB(QString s){ strB = s; }
   QString get(){ return str; }
   QString getB(){ return strB; }
 
protected:
   QString strB;
 
};
 
class C : public A
{
public:
   void set(QString s){ str = s; }
   void setC(QString s){ strC = s; }
   QString get(){ return str; }
   QString getC(){ return strC; }
 
protected:
   QString strC;
 
};
 
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
 
   QMap<QString, A> map;
   B b;
   b.set("class B set");
   C c;
   c.set("class C set");
 
   map.insert("B",b);
   map.insert("C",c);
 
   QString bb = map["B"].get();
   QString cc = map["C"].getC(); // error: 'class A' has no member named 'getC'
 
   qDebug() << map.size() << " " << bb << " " << cc;
 
   return a.exec();
}
 


Название: Re: Как потомков из базового класса "засунуть" в один список ?
Отправлено: shirushizo от Апрель 12, 2010, 06:56
Верное решение тебе уже написали:
засовывать надо указатель на экземпляры наследников как указатель на базового класса а не сами экземпляры наследников - если это наследники QObject то можно кастить через qobject_cast
иначе через static_cast и др. стандартные конструкции приведения типов C++ в зав. от ситуации ( dynamic_cast, reinterprep_cast и др. )
что тебе мешает сделать так:
Код:
QMap<QString,A*> map;
...
QString cc= (static_cast<C*>(map["C"]))->getC();
Это ж одна из "плюшек" наследования  ;)


Название: Re: Как потомков из базового класса "засунуть" в один список ?
Отправлено: MoPDoBoPoT от Апрель 12, 2010, 12:34
Еще, в зависимости от того, что в действительности представляет из себя класс A и его наследники, а также для чего методы getB()/getC(), можно в классе A сделать сделать чисто виртуальный метод getValue(), а в конкретном классе реализовать конкретный функционал.
Все зависит от конкретной ситуации.


Название: Re: Как потомков из базового класса "засунуть" в один список ?
Отправлено: shirushizo от Апрель 12, 2010, 19:47
В принципе, да, если функции/поля в обоих наследниках, то их нужно вынести в родителя. А если делают одно и тоже, но отличаются в реализации, то лучше сделать метод виртуальным и вынести в родителя.


Название: Re: Как потомков из базового класса "засунуть" в один список ?
Отправлено: Amigo_sa от Апрель 13, 2010, 14:47
static_cast - это суровая диктатура...