freeboy1015
freeboy1015

Reputation: 2337

what is a reason for which RTTI is considered as a bad design?

what is a reason for which RTTI is considered as a bad design?
Stroustrup has written in his book TC++PL that the most common case of usage RTTI technique is with switch instruction, when one want to decide what code should be executed basing on what is a "real" type of a passed object. There is given an example in which an object of shape class was passed to the function and different actions were executed depending on that whether a shape is circle, square, triangle, etc. He has written that such construction is a sign that one should replace the switch-case sequence by virtual functions.

Upvotes: 1

Views: 2670

Answers (1)

Michael Anderson
Michael Anderson

Reputation: 73440

RTTI only works if your classes have a virtual table. If you have a virtual table you can implement virtual functions. The reason you should use virtual functions over a switch on the type of the object is that it works better with inheritance chains, and is less fragile when adding new classes.

For example:

class A : public V {}
class B : public V{}

void do_something( const V & v )
{
  if (typeid(A) == typeid(v)) { .. its an A .. }
  if (typeid(B) == typeid(v)) { .. its a B .. }
}

int main()
{
   do_something( A() ); 
   do_something( B() );
}

Now if we add a new class C also derived from V and call do_something( C() ) (without changing the implementation of do_something) , nothing will happen. (No error at compile time). If we add a class D derived from A also no error and nothing happens.

Contrast this with the behaviour for virtual functions

struct V 
{
   virtual void do_something() const =0;
};

struct A
{
  virtual void do_something() const { ... its an A ... }
}

struct B
{
  virtual void do_somethine() const { ... its a B ... }
}

void do_something( const V & v )
{
  v.do_something();
}

Now if we derive C from V and don't implement C::do_something() we'll get a compile time error. If we derive D from A and dont implent D::do_something() we'll get calls to A::do_something().

So this is the primary reason virtual functions are prefered over RTTI. However sometimes you may feel that the behaviuor of do_something doesn't belong in your V or A B C classes. So you'd be tempted to use RTTI (either by typeid or dynamic_cast). A better solution is often to implement the visitor pattern for the class hierarchy.

Upvotes: 2

Related Questions