Question

I have a base class which has two child classes derived from it.

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

I have another class that has a pointer to collection of class A members using a vector, something like this:

vector<A*> *m_collection;

And what I do is to create objects of class B or C and add them to the collection using push_back:

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

Then I loop through the collection and try to check using 'typeid', but it always returns the base class (A). Is it not possible to know the exact type?

Thank you!

Was it helpful?

Solution

Firstly, there is unlikely to be a reason to create your vector dynamically using new. Simply say:

vector<A*> m_collection;

Then you need to give your base class a virtual function or two. A virtual destructor would be a good start:

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

without it you cannot safely write code like:

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

Doing this will also enable run-time type information. Howver, switching on typeid is not how C++ likes you to use RTTI - you should use 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";
}

In general however, it is better to use the virtual function mechanism for dispatch, rather than RTTI.

OTHER TIPS

W.r.t. typeid, you need to have a virtual function in your base class (A) (the vtable usually sits near the std::type_info structure), then you must dereference the object, i.e. typeid(*b).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top