【问题标题】:C++ Composition - must I wrap all those functions?C++ 组合 - 我必须包装所有这些函数吗?
【发布时间】:2013-06-04 05:08:31
【问题描述】:

我有一个 C++ 类,它描述了对象在 3D 空间中的方向 - 位置、旋转、缩放等。我还有其他类必须需要类似的信息(或其子集) - 模型、地形、相机等等。现在我可以创建我的方向类的这些子类,但谷歌告诉我更喜欢组合而不是继承。这在哲学上是有道理的——模型不是一个方向,它一个(是的,我知道is-a has-a只是一种启发式)。然而,为所有那些可能的子类重写相同的包装方法似乎是不必要的,几乎是可笑的不雅,只是去获得那个功能。 model.getOrientation().set_x(1) 之类的东西似乎也很愚蠢。

我明白为什么这对于小物体来说不会“太糟糕”,但是对于这个例子(以及其他类似的例子),如果你必须通过箍来假装,那么构图的意义何在你正在使用继承?我现在应该使用它吗?我几乎可以肯定我在考虑这个问题。

【问题讨论】:

  • model.orientation.set_x(1) 有什么问题?
  • @Lol4t0 看起来很冗长。另外,你不应该只是能够告诉一个对象做某事而无需拆卸它,可以这么说吗?也许类似的设计模式实例会有所帮助?
  • 问题是设置方向并不是告诉对象要做什么(如果对象不是方向)。那!实际上是一个问题。您不应该为对象设置方向,而应该用他们的术语与他们交谈,例如 monster->attack()camera->zoom()

标签: c++ oop inheritance composition


【解决方案1】:

为有方向的事物编写一个类。让模型、地形、相机等从该类继承。如果你想做任何包装,你只需要在一个班级里做。使用 getter 以便您可以更改方向在对象中的存储方式。

【讨论】:

  • 这与仅仅扩展定位类有何不同?
  • 它更清楚地表达了想法。正如你所说,模型不是方向。
  • 我喜欢这个主意。您不会通过从 orientation 类继承它而耦合到它所具有的所有内容,您可以从 orientation 类中正确封装您需要的任何内容,然后通过从这个中间类继承来重新使用那些封装的属性/方法(假设模型、地形、相机都使用来自orientation 对象的相同特征子集)
  • 我个人认为这只是作弊。当你做这样的事情时,模式会让你摇摆不定。 (我的意思是,万一你包装了方向的整个界面,不仅仅是Orientation& orientation()函数)
【解决方案2】:

这可能看起来很傻,但你的 model.getOrientation().set_x(1) 可能是要走的路。

如果您厌倦了键入 getOrientation() 部分,您可以尝试以下操作:

Orientation & orient = model.getOrientation();
orient.set_x(1);
orient.set_y(1);
if( orient.check_something() ) {
  //whatever
}
//etc.

【讨论】:

  • 我倾向于这个。其他人似乎同意你的回答。您能否详细说明为什么这是最好/首选的方法?
  • 1.很少或没有样板 2. 保持正确的 is-a/has-a 关系。 3. 是惯用的:不会混淆其他程序员
【解决方案3】:

有一种便宜的方法可以避免大部分包装样板。

class model : private orientation {
  public:
    using orientation::set_x;
    ... etc ...
};

C++ 中的私有继承并不(必然)意味着“是一个”。它对外界来说或多或少是不可见的,有时被描述为“以 a 的形式实现”的意思。也就是说,您获得了一种有限的组合形式,这有助于您公开组合对象的部分或全部接口。

【讨论】:

    猜你喜欢
    • 2013-07-18
    • 1970-01-01
    • 2016-11-13
    • 2021-09-13
    • 2011-08-17
    • 2011-09-17
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多