Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is usage of the typeid keyword bad design?

Tags:

c++

typeid

I have heard a lot of people say any usage of typeid is bad design, yet to me it seems like it offers great utility.

  1. When (and why) is usage of typeid "bad design"?
  2. When is usage of typeid acceptable?
  3. When it is not acceptable, but you still need something alike, what would an alternative be that would have good design?
like image 430
xcrypt Avatar asked Mar 03 '12 15:03

xcrypt


People also ask

Is Typeid slow?

typeid() can be much faster than other type checks if all the stars are aligned, or it can be extremely slow. typeid() requires the compiler to determine if a pointer is null, so if you already know your pointer is non-null, it's more efficient to use typeid() on a reference instead.

What is Typeid used for?

The typeid operator allows the type of an object to be determined at run time. The result of typeid is a const type_info& . The value is a reference to a type_info object that represents either the type-id or the type of the expression, depending on which form of typeid is used.

What does typeid return?

The typeid operator returns an lvalue of type const type_info that represents the type of our value.

What does Typeid name return C++?

The typeid operator returns an lvalue of type const std::type_info that represents the type of expression expr. You must include the standard template library header <typeinfo> to use the typeid operator. Classes A and B are polymorphic; classes C and D are not.


2 Answers

The problem isn't with typeid. The problem is that seeing typeid would encourage you to write this:

PolymorphicType *pType = ...;
if(typeid(*pType) == typeid(Derived1))
  pType->Func1();
else if(typeid(*pType) == typeid(Derived2))
  pType->Func2();
else if(typeid(*pType) == typeid(Derived3))
  pType->Func3();

This is what we call "really stupid". This is a virtual function call done in about the least reasonable way possible. typeid has the potential for abuse when used to replace dynamic_cast and virtual functions.

This example may sound far-fetched. After all, it's obvious that this is just a virtual call. But bad code often grows from the path of least resistance; all it takes is for one person to do a typeid() == typeid(), and the seed of this code has begin. In general, if you're directly using typeid frequently, odds are very good that you're doing something that could be better done with other language constructs.

typeid is the polymorphic type deduction method of last resort.

Is all usage of typeid wrong? Of course not. boost::any wouldn't be possible without it. Well it would be possible, but it wouldn't be any safer than void*. typeid is what makes type-safe boost::any type erasure possible. There are other legitimate uses of it.

But in code-lines-to-use ratio, I would suggest it should be in about one in 10,000 lines of code, at most. Much fewer than that, and you're probably using it wrong.

Is type checking slow?

In general, the main reason to call typeid is either in templated code (as in boost::any) or when you're expecting a polymorphic type. If the type is statically determined (ie: a typename or value of a non-polymorphic type is given), then you can expect it to be done at compile-time.

It's polymorphic values you should be concerned about. I've seen a performance test that showed that some typeid implementations actually walk the class hierarchy, so the time it takes for them to find the type is proportional to the number of classes between the real type and the given type. Every implementation will be different, but that's a pretty good indication that maybe you shouldn't put it in performance-critical code.

like image 129
Nicol Bolas Avatar answered Oct 31 '22 18:10

Nicol Bolas


I don't think anyone says that usage of typeid is itself bad design; rather, what you'll hear is that usage of typeid is indicative of bad design. The idea there is that any logic that distinguishes (say) Square from Circle should actually be in those classes, so should be expressed by a virtual function (polymorphism).

Needless to say, this is not an absolute rule.

like image 45
ruakh Avatar answered Oct 31 '22 19:10

ruakh