Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static_cast and RTTI vs dynamic_cast

Please observe the below code. As far as i know, dynamic_cast is slower than static_cast. Because it evaluates the type at runtime. My doubt here is if we use static_cast with typeid() as below , will it takes same time as dynamic cast ?? Will it be faster than dynamic_cast ?

class Shape
{ 
public:
  virtual ~Shape(){}
};
class Circle : public Shape{ };
class Square : public Shape{ };

Static cast with RTTI:

Circle c;
Shape* s = &c; // Upcast: normal and OK

// More explicit but unnecessary:
s = static_cast<Shape*>(&c);
// (Since upcasting is such a safe and common
// operation, the cast becomes cluttering)

Circle* cp = 0;
Square* sp = 0;

// Static Navigation of class hierarchies
// requires extra type information:
if(typeid(s) == typeid(cp)) // C++ RTTI
    cp = static_cast<Circle*>(s);
if(typeid(s) == typeid(sp))
    sp = static_cast<Square*>(s);
if(cp != 0)
    cout << "It's a circle!" << endl;
if(sp != 0)
    cout << "It's a square!" << endl;

Dynamic cast:

Circle c;
Shape* s = &c; // Upcast: normal and OK

s = &c;
Circle* cp = 0;
Square* sp = 0;
cp = dynamic_cast<Circle*>(s);
    if(cp != 0)
    cout << "It's a circle!" << endl;
sp = dynamic_cast<Square*>(s);
if(sp != 0)
    cout << "It's a square!" << endl;
like image 402
ranganath111 Avatar asked Nov 30 '25 02:11

ranganath111


2 Answers

It is faster to test the type and then do the static_cast, but the operations are not equivalent as that will only allow downcast to the most derived type (any intermediate level will not be matched with the typeid). I would use dynamic_cast as it is more robust (will not break if someone extends your type and passes a pointer, for example).

If performance of dynamic_cast is an issue in your application, you should reconsider the design. While typeid + static_cast is faster than dynamic_cast, not having to switch on the runtime type of the object is faster than any of them.

like image 145
David Rodríguez - dribeas Avatar answered Dec 06 '25 21:12

David Rodríguez - dribeas


Those code samples are not logically the same. You forgot that dynamic_cast takes class inheritance into the account, and comparing typeid() compares only the leaf part of the inheritance tree. The only thing the typeid gives you is the "some unique identifier related to the actual type of that object". With typeid() alone you cannot check whether a cast to a pointer of a common base is possible, you can check only if the runtimetype-of-that is exactly the same as runtimetype-of-otherthing.

Saying that, I think that static_cast+typeid should be a somwhat faster in the general sense, but will simply give wrong answers in some cases.

like image 35
quetzalcoatl Avatar answered Dec 06 '25 20:12

quetzalcoatl