tags:

views:

121

answers:

2

Hello,

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!

+4  A: 

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.

anon
Why is dynamic_cast<> preferred to directly using typeid ?
Hassan Syed
@Hassan: I don't think it should be. You should also be able to use typeid and follow that with a static_cast. (Might be more efficient, since checking typeid could be a lot simpler than dynamic_cast.) However, still the existance of virtual methods would be required.
UncleBens
dynamic_cast is safer - this is BS's opinion, as well as my own.
anon
Usign the dynamic_cast does not imply you are using RTTI? What is actually confirm the use of it?
Julen
@Julen dynamic_cast requires RTTI. You can confirm this by turning RTTI off (if your compiler supports this).
anon
I am using GCC right now, I work using automake/autoconf (quite misterious but useful to me) and I don't know exactly how to turn it off... :-(
Julen
A: 

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).

Marcus Lindblom