c++ - 我应该如何在 C++ 中表示继承对象树?

标签 c++ inheritance tree polymorphism

<分区>

例如,我有继承自 CParentis 的类 CPrimusCSecundusCTertius,我想实现一个对象树,其中的叶子(节点?)可以是任何一个派生类的实例,例如:

  • CPrimus
    • CTertius
  • CPrimus
    • CSecundus
      • CTertius
      • CTertius
  • CSecundus
    • CTertius
      • CPrimus
    • CTertius
      • CSecundus
      • CPrimus

在 C++ 中实现此树的最佳*方法是什么?可能需要对类进行哪些修改才能支持它?

(*) 我会将“最佳”的定义留给社区,无论是“最快”、“最有效”、“最漂亮”还是您喜欢的任何东西。我个人偏爱简单和高效,但如果 yield 值得的话,我愿意为性能牺牲简单性。此外,如果您要建议 BGL,请尝试给出示例,或者至少链接到解释如何实现树的文章或文档的特定部分。

编辑:

由于这个问题有点过于笼统,我将给出一个潜在的用例。在 Linux 中,文件系统(通常)位于裸分区、MD 阵列或 LVM 逻辑卷之上。假设我希望我的类表示这些结构并存储有关它们的元数据(设备名称、大小、uuid 等)以供以后检索,并且基类具有一组用于刷新和检索元数据的虚函数。

现在,假设我的系统有这样的磁盘布局:

  • [FS-/引导]
    • [ARR-md0]
      • [部分sda1]
      • [部分-sdb1]
  • [FS-/]
    • [LV-根]
      • [VG-系统]
        • [ARR-md1]
          • [部分sda2]
          • [部分sdb2]

我如何将其表示为 C++ 数据结构?

最佳答案

啊是的,有多个问题。

<强>1。 container 没有标准的容器,你可以自己做,但是要完成它需要做很多工作。我发现的最好的东西是 Tree Container Library - 免费且有据可查。我没有将它置于重负载下,但它“看起来不错”是一个有效的实现。

<强>2。多态容器 - 即具有不同类型作为元素的容器 - 在 C++ 中有点麻烦。但是,由于您已经拥有一个共享基类,因此您有很多选择。

  • [编辑] CParentis 中的虚方法。
  • static_cast:您将项目存储为 CParentis *(或更好的智能指针)。如果对于 CParentis * 您知道它实际是什么类型,您可以使用 static_cast 对其进行强制转换
  • dynamic_cast:与上面相同,但 dynamic_cast 将使用运行时类型信息,您可以“探测”不同的类型。但是,根据类继承关系和编译器,它可能会比较慢(游戏开发人员讨厌它,因为在大多数编译器下,它无法在渲染场景时处理数千个对象)
  • boost::any : 这是来自 boost 的一段很棒的代码,它可以让你存储任何类型,并在以后查找它。类似于 dynamic_cast,但不需要共享基类。但是,需要额外的分配 - 对于数百万个对象来说可能是个问题。
  • boost::variant : 类似于 boost:any,但对于一组预定义的类型,开销更少。

如果您使用 static_cast 路由,则需要为您的类添加一个类型标识符(或使用 typeof)。但是,切换类型以启用特定处理是一种代码味道,因为它会随着所涉及的类数/对象数而严重扩展。扩展性更好的解决方案是共享抽象基类(当操作事先已知时)或访问者模式(当您需要稍后进行其他操作时)。

最后,最小的:如果房间里有 comp sci 专业,永远不要称它为树。他会用他的电子书阅读器猛击你的脑袋,解释说这是一个有向无环图,然后提示你弄坏了他的玩具(至少,我想象我们的计算机科学人员如果有一本电子书就会这样做读者……)

关于c++ - 我应该如何在 C++ 中表示继承对象树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6849843/

相关文章:

extjs - 单击父级时检查树的子级节点[ExtJS]

ruby-on-rails - 使用闭包表模式实现版本历史

c++ - 将 5x5 矩阵减少到 c 中的 25 元素数组

c++ - 重载 << 并定义流操纵器 C++

java - 如果我已经完成向上转换,为什么要重写从子类调用的方法?

c++ - 在 C++ 中访问继承类的特定方法

c++ - 二叉索引树应用于按位与

c++ - 模板非类型模板参数?

c++ - Lubuntu 中的 QT 控制台应用程序

html - 在页脚中下拉菜单