Как получить тип объекта из коллекции (вектора) родительских объектов, используя RTTI - PullRequest
0 голосов
/ 09 февраля 2010

У меня есть базовый класс, в котором есть два дочерних класса.

class A {};
class B : public A {};
class C : public A {};

У меня есть другой класс, у которого есть указатель на коллекцию членов класса A, использующих вектор, что-то вроде этого:

vector<A*> *m_collection;

И что я делаю, это создаю объекты класса B или C и добавляю их в коллекцию, используя push_back:

B *myb = new B();
m_collection->push_back(myb);

Затем я перебираю коллекцию и пытаюсь проверить, используя 'typeid', но он всегда возвращает базовый класс (A). Разве невозможно узнать точный тип?

Спасибо!

Ответы [ 2 ]

4 голосов
/ 09 февраля 2010

Во-первых, вряд ли есть причина для динамического создания вектора с использованием new. Просто скажи:

vector<A*> m_collection;

Тогда вам нужно дать вашему базовому классу виртуальную функцию или две. Виртуальный деструктор был бы хорошим началом:

class A {
   public:
     virtual ~A() {}
};

без него вы не можете безопасно написать код, подобный:

m_collection.push_back( new B );
delete m_collection[0];

Это также активирует информацию о типе во время выполнения. Однако, включение typeid - это не то, как C ++ нравится, когда вы используете RTTI - вы должны использовать dynamic_cast:

m_collection.push_back( new B );    // or new A or new C
if ( C * c = dynamic_cast<C *>( m_collection[0] ) ) {
   c->CFunc():  // function in C
}
else if ( B * b = dynamic_cast<B *>( m_collection[0] ) ) {
   b->BFunc():  // function in B
}
else if ( A * a = dynamic_cast<A *>( m_collection[0] ) ) {
   a->AFunc():  // function in A
}
else {
  throw "unknown type";
}

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

0 голосов
/ 09 февраля 2010

W.r.t. typeid, вам нужно иметь виртуальную функцию в вашем базовом классе (A) (виртуальная таблица обычно находится рядом со структурой std :: type_info), тогда вы должны разыменовать объект, то есть typeid(*b).

...