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

标签 c++

<分区>

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

关于c++ - dynamic_cast 被引入 C++ 以破坏多态性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39896772/

相关文章:

c++ - 使用可变模板中的参数定义多个方法

c++ - 是否可以隐藏 arduino 的库代码?

c++ - 从 CMake 创建 Visual Studio 项目,Visual Studio 找不到可执行文件

c++ - 使用 CMake 对 `shm_open' 的 undefined reference

c++ - 为什么没有 C++11 线程安全替代 std::localtime 和 std::gmtime?

c++ - STL 容器中的 max_size 由什么决定?

c++ - Freetype 和 OpenGL 的问题

c++ - 另一个 C++ 对象初始化询问

c++ - 为什么排序算法会死循环

c++ - QSortFilterProxyModel 崩溃的应用程序