c++ - 如何在设计层面移除 dynamic_cast

标签 c++

需要 dynamic_cast 通常被认为是糟糕的设计。然后考虑这种情况:

  • 1个抽象基类ABC;
  • 100个派生类D1, D2...D100;
  • 一个实时处理 100'000 个 Ds 对象的应用程序;

那些 Ds 对象需要存储在某个容器中,所以我将它们存储为 ABC*

当我需要搜索特定类型的节点时,我需要将它们全部dynamic_cast 并返回“好的节点”。存在 dynamic_cast 的替代方案,但它们的实现细节多于严格的设计:

  • 使用虚拟方法:AsD23() 返回一个 D23* 如果 this 是一个 D23* 并且nullptr 否则;
  • 使用 typeId + static_cast;

在这两种选择中,唯一改变的是检查 ABC 是否实际上是 D42 的方法。这就是为什么我认为这更多的是实现细节而不是设计选择。 我说得对吗?

那么,如果是,在这种特殊情况下,在设计方面什么是好的替代方案(如果有的话)?

最佳答案

一种方法是更改​​容器:使用 std::multimap<std::type_index,ABC*> (或者 std::unordered_multimap<std::type_index,ABC*> 如果你可以访问 C++11)来存储你的对象,使用它们的 type_id作为键( std::type_index 扭曲 type_id )。通过这种方式,您可以非常快速地获得特定类型 - 在对数时间内使用 std::multimap或在恒定时间内使用 std::unordered_multimap (当然,迭代实际对象与需要迭代的特定类的对象数量成线性关系)。

这种方法的一个缺点是它依赖于 type_id : 它可以让你快速到达一个特定的子类,但如果你的类型层次结构在未来变得更复杂,比如说,你添加 ABC 的子类,比如说,BCD1 , BCD2 , ..., 作为您派生类型的一些 的基类,上述方法不允许您搜索 BCDx 的所有对象,因为您需要传递“最终”类型的 ID,即 D... 之一

请注意,在容器中使用原始指针并不理想 - 考虑将其替换为智能指针,例如 std::unique_ptr<ABC>std::shared_ptr<ABC> .

关于c++ - 如何在设计层面移除 dynamic_cast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24323243/

相关文章:

c++ - 如何在多配置项目中管理第三方库

c++ - 我怎样才能画笔宽度为 0(不可见而不是化妆品)?

c++ - 一个类是 POD 从二进制文件中读取它就足够了吗?

c++ - Eigen 二维叉积

c++ - 在 C++ 中替换对象自身

c++ - 缓冲区溢出示例:为什么此代码很危险?

C++ fstream 如何从文本文件中读取特定行

c++ - 了解 bash 中程序使用的内存(在 ubuntu linux 中)

c++ - 我可以在 android studio 中使用用 xcode 编译的 c++ 静态库吗?

c++ - Windows API 函数 CredUIPromptForWindowsCredentials 也返回错误 31