B. Stroustrup 最初将 C++ 设计为没有 dynamic_cast
,但后来人们不得不将这种类型转换添加到语言中。无论我在哪里遇到 dynamic_cast
的用法,它都反对对象的多态使用。所以有时您更愿意知道对象类型,而不是尝试重新设计代码以利用多态性?那些是什么情况?你能举出一个例子吗?
附言请考虑 dynamic_cast
将大量 RTTI 信息添加到代码中,这是添加到语言中的部分反射,因为类层次结构信息存储在编译代码中。这违背了 C++ 哲学——你为你使用的东西付费。 (我知道您可以关闭 RTTI,但默认情况下它是打开的,您可能一次都不需要在整个代码中使用它!)
编辑:根据@Griwes 的评论,RTTI 的转向是可能的,但这是未定义的行为。因此,上述与 C++ 哲学相关的结论变得更加有力。
首先,RTTI 信息量不大。它包括代码的只读部分中的一些信息,以及虚拟表中的一个附加条目。从这个意义上说,异常的代价要高得多(除非抛出异常,否则 CPU 将永远不会运行某些生成的代码的实际复制)。
C++ 的哲学是,而且一直是,为您提供工具,您可以使用这些工具来改进您的代码,但不能保护您免受这些工具的不良使用。如果您看到人们滥用动态转换,那就太糟糕了,但 C++ 并不认为这是设计失败(只不过是多重继承)。
就个人而言,我喜欢仅将动态转换用作断言。换句话说,我构建了一个向下转换类的设计,我应该已经知道我向下转换到什么类型。然后我使用动态转换来确保我的设计没有被破坏,我认为这确实是正确的类型。
这是必要的原因是因为您不能用返回不同返回类型的方法覆盖方法。如果你有 A,B 和 C 继承自它,你不能让 A 包含:
class A {
...
virtual A *some_method();
};
然后有:
class B : public A {
...
override virtual B* some_method();
};
C++ 根本不允许这样做。由于这是不允许的,因此可能需要采用 some_method
的返回值,并将其从 A*
转换为 B*
。当你这样做时,最好确保你手头确实有一个 B
的实例,而不是例如 C
。