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

时间:2016-10-06 13:02:50

标签: c++

B中。 Stroustrup最初设计的C ++没有dynamic_cast,但是后来人们必须添加一些强制转换为语言的东西。无论我在哪里遇到dynamic_cast的使用,都反对对象的多态使用。所以有时你会更喜欢知道对象类型,而不是试图重新设计你的代码来利用多态?那是什么案例?你能举一个例子吗?

P.S。请考虑dynamic_cast在代码中添加大量RTTI信息,这是部分反射添加到语言中,因为类层次结构信息存储在编译代码中。这是违反C ++哲学的 - 你为你使用的东西买单。 (我知道你可以关闭RTTI,但默认情况下它已启用,你可能不需要在整个代码中使用它而不是一次!)

编辑:根据@Griwes的评论,转向RTTI是可能的,但这是未定义的行为。因此,上述与C ++哲学相关的结论变得更加强大。

1 个答案:

答案 0 :(得分:0)

首先,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