【问题标题】:C++: tall class hierarchiesC++:高层类层次结构
【发布时间】:2011-05-19 17:22:09
【问题描述】:

具有类层次结构的运行时缺点是什么?

我们将H称为层次结构的高度(即:从基类到叶子要遍历多少类)。

dynamic_cast 将花费更多:它花费O(H)

是否有其他运算符或语言功能受到影响?

【问题讨论】:

  • 开发人员算不算“运营商”?他们会受苦的:)

标签: c++ class inheritance height hierarchy


【解决方案1】:

叶类对象的构造和销毁需要更长的时间,因为层次结构中的所有构造函数都被调用(从基类到叶类)。

【讨论】:

  • 嘿,这些不能被认为是“开销”,因为它们是代码功能的一部分!
  • 我同意@ybungalobill 的观点。无论您是构建基类对象还是成员对象,成本都没有什么不同,因此这不是由于继承而引入的成本。
  • @ybungalobill:我想这取决于您的构造函数是否内联。如果您像我一样不喜欢内联它们(使更改它们不那么痛苦),那么这将更加昂贵,因为会有更多的“调用”(不参与功能)。
  • @Matthieu:但是如果它们是构造成员而不是基类,它们也不会被内联,不是吗?看,无论您如何设计那些与您的类相关的子对象(基础、成员、外部对象等),它们需要被构造。将它们塞进一个高等级的等级体系(我以前从未听说过的一个术语,但它确实有意义)不会改变任何这一切。这几乎是一个纯粹的编译器前端问题。 struct X : Y {}; 可能生成与struct X { Y y; };(或struct X {}; Y y;,FTM)完全相同的代码。我认为这是 ybungalobill 批评的核心。
【解决方案2】:

所有的操作都可以在 O(1) 时间内完成,通常都是,除了dynamic_cast。对于静态链接库,最后一个可以在 O(1) 时间内实现,请参阅here

【讨论】:

    【解决方案3】:

    主要问题是可维护性。深层类层次结构可能没有正确建模。任何超过 3-4 个级别的内容都应该让您警觉。您可能是从具体类派生的,这是您永远不应该做的事情(Liskov Substitution principle 不允许这样做)。如果您的基类中充斥着virtual 函数(我的意思是不是纯粹的),那么重构将会很困难。

    将您的基类拆分为几个不同的接口 (Interface Segregation)。更喜欢组合而不是继承(软件设计的 GoF fundamental rule)。

    个人建议:尝试在没有dynamic_cast 的情况下进行编程。当我还是 C++ 开发人员时,我能够在没有 dynamic_cast 的情况下完全编程。我在适当的地方使用了设计模式、工厂、visitors 等。没有演员表,生活会简单得多:-)。

    祝你好运!

    【讨论】:

    • LSP 并没有明确禁止从具体类派生(但是在不违反 LSP 的情况下很难有意义地做到这一点)。但这通常(总是?)是个坏主意。不过,一个非常好的答案。
    • 我当然同意。我避免使用dynamic_cast,但我试图找出 C++ 特性的成本取决于层次结构的高度。 tall 类也不常见(也是不好的做法),除非您经常使用模板;例如查看boost::operators
    • @peoro: boost::operators 和其他元模板编程技术(如类型列表)是相当极端的情况。注意(例如) boost::operators 没有virtual 方法,不能用作传统的基类。我可能会在一边继承它们(使用多重继承),因为它们是空基,我们可以在这里希望 EBO。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    相关资源
    最近更新 更多