Code and Stuff

Feb 13, 2013

C++ Polymorphic

Used to Java I was quite surprised to discover that the RTTI of C++ works "polymorphic" only when the classes contain at least one virtual method. This means that if we have two classes, A and B where B inherits from A, and we ask for the typeid of an instance of B from a dereferenced A pointer, RTTI will tell us the type is B only if A has a virtual method otherwise it will tell us the type is A.

This is best shown in code:

#include <iostream>
#include <typeinfo>

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

class VA {
  virtual void dummy(){ }; 
};

class VB : public VA { };

int main() {
  B* b = new B; // typeid is B, ok
  A* a = new B; // typeid is A!

  std::cout << "b: " << typeid(*b).name() << std::endl;
  std::cout << "a: " << typeid(*a).name() << std::endl;

  VB* vb = new VB; // typeid is VB, ok
  VA* va = new VB; // typeid is VB, just like java :-)

  std::cout << "vb: " << typeid(*vb).name() << std::endl;
  std::cout << "va: " << typeid(*va).name() << std::endl;
  return 0;
}
will output the following:
b: 1B
a: 1A
vb: 2VB
va: 2VB
The second line tells us that the type is A even if we created the object with "new B".

This implies that we will not be allowed to dynamic_cast an A pointer to a B one. gcc will reports that the cast is not permitted becase the "source type is not polymorphic".

A* a = new B;
B* c = dynamic_cast<B*>(a); // compilation error
It is, however, perfectly fine to cast the classes with the virtual method:
VA* va = new VB;
VB* vc = dynamic_cast<VB*>(va);

No comments: