0

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!

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
Julen
  • 1,574
  • 3
  • 22
  • 38
  • Don't try to format your code using HTML tags - use the formatting buttons above the text editing area. –  Feb 09 '10 at 17:43
  • The best way to do markup of a block of code is to indent it four spaces. That automatically escapes special characters like "<". – sth Feb 09 '10 at 17:44

2 Answers2

4

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.

  • Why is dynamic_cast<> preferred to directly using typeid ? – Hassan Syed Feb 09 '10 at 18:12
  • @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 Feb 09 '10 at 18:19
  • dynamic_cast is safer - this is BS's opinion, as well as my own. –  Feb 09 '10 at 18:28
  • Usign the dynamic_cast does not imply you are using RTTI? What is actually confirm the use of it? – Julen Feb 11 '10 at 21:41
  • @Julen dynamic_cast requires RTTI. You can confirm this by turning RTTI off (if your compiler supports this). –  Feb 11 '10 at 21:47
  • 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 Feb 13 '10 at 16:41
0

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

Macke
  • 24,812
  • 7
  • 82
  • 118