Search code examples
c++vectorrtti

How to get the object type from a collection (vector) of parent objects using RTTI


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!


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.