问题描述
我听说很多人说任何使用 typeid
是不好的设计,但对我来说,它似乎提供了很大的实用性。
- 何时(以及为什么)使用
typeid
坏设计? - 何时使用
typeid
可以接受? - 如果不能接受,但仍需要类似的东西, 与
typeid
。问题是看到typeid
会鼓励你这样写: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
这就是我们所说的真蠢。这是一个虚拟函数调用以尽可能最不合理的方式完成。
typeid
在用于替换dynamic_cast
和虚拟
函数。
此示例可能听起来很牵强。毕竟,很明显这只是一个虚拟调用。但是坏代码通常从最小阻力的路径增长;所有它需要一个人做一个
typeid()== typeid()
,这个代码的种子已经开始。一般来说,如果你经常直接使用typeid
,赔率是非常好的,你可以做一些更好的其他语言结构。
typeid
是 last resort的多态类型推导方法。
是否所有使用
typeid
错误?当然不是。boost :: any
将不可能没有它。这可能是可能,但它不会比void *
更安全。typeid
是什么使得类型安全boost :: any
类型擦除成为可能。还有其他合法用途。
但是在代码行使用率,我建议它应该在大约一万行代码,在最。
一般来说,调用
typeid
的主要原因是模板代码(如boost :: any
)或者当你需要一个多态类型。如果类型是静态确定的(即:给定类型名或非多态类型的值),那么您可以期望它在编译时完成。
它是你应该关注的多态值。我看到一个性能测试,显示一些
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.- When (and why) is usage of
typeid
"bad design"? - When is usage of
typeid
acceptable? - When it is not acceptable, but you still need something alike, whatwould an alternative be that would have good design?
解决方案The problem isn't with
typeid
. The problem is that seeingtypeid
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 replacedynamic_cast
andvirtual
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 usingtypeid
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 thanvoid*
.typeid
is what makes type-safeboost::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.
In general, the main reason to call
typeid
is either in templated code (as inboost::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.这篇关于为什么使用typeid关键字坏设计?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
- When (and why) is usage of