dynamic_cast被引入C++以破坏多态性

dynamic_cast was introduced to C++ to ruin polymorphism?

本文关键字:多态性 C++ cast dynamic      更新时间:2023-10-16

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