C++;组合-我必须包装所有这些函数吗? 我有一个C++类,描述了一个物体在三维空间中的方位-位置、旋转、比例等。我有其他的类,它必然需要像这样的信息(或者它的一个子集)——模型、地形、摄像机等。现在我可以把我的方位类的子类,但是谷歌告诉我,比起继承,更喜欢合成。这在哲学上是有道理的——一个模型不是一个方向,它有一个方向(是的,我知道is-a has-a东西只是一个启发性的东西)。然而,为所有那些可能的子类重写相同的包装器方法似乎是不必要的,几乎是滑稽的不雅的,只是去获取那个功能。像model.getOrientation().set_x(1)这样的事情看起来也很愚蠢

C++;组合-我必须包装所有这些函数吗? 我有一个C++类,描述了一个物体在三维空间中的方位-位置、旋转、比例等。我有其他的类,它必然需要像这样的信息(或者它的一个子集)——模型、地形、摄像机等。现在我可以把我的方位类的子类,但是谷歌告诉我,比起继承,更喜欢合成。这在哲学上是有道理的——一个模型不是一个方向,它有一个方向(是的,我知道is-a has-a东西只是一个启发性的东西)。然而,为所有那些可能的子类重写相同的包装器方法似乎是不必要的,几乎是滑稽的不雅的,只是去获取那个功能。像model.getOrientation().set_x(1)这样的事情看起来也很愚蠢,c++,oop,inheritance,composition,C++,Oop,Inheritance,Composition,我可以理解为什么这对于小对象来说不是“太糟糕”,但是对于这个例子(以及其他类似的例子),如果你不得不通过各种手段来假装你在使用继承,那么合成有什么意义呢?我现在应该使用它吗?我几乎可以肯定我想得不恰当 为有方向的事物编写一个类。让模型、地形、摄影机等从该类继承。如果你想做任何包装,你只需要在一节课上做。使用getter可以更改方向在对象中的存储方式。这可能看起来很愚蠢,但您的模型.getOrientation().set_x(1)可能是最好的选择 如果您厌倦了键入getOrientation()

我可以理解为什么这对于小对象来说不是“太糟糕”,但是对于这个例子(以及其他类似的例子),如果你不得不通过各种手段来假装你在使用继承,那么合成有什么意义呢?我现在应该使用它吗?我几乎可以肯定我想得不恰当

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

这可能看起来很愚蠢,但您的
模型.getOrientation().set_x(1)
可能是最好的选择

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

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

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

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

< C++中的私有继承并不一定意味着“是”。它对局外人来说或多或少是看不见的,有时被描述为“是以一种方式实现的”。也就是说,您得到了一种有限的合成形式,它有助于您公开合成对象的部分或全部接口。

model.orientation.set_x(1)?@Lol4t0它似乎很冗长。另外,可以这么说,你不应该只告诉一个物体去做某件事而不拆卸它吗?也许类似的设计模式实例会有所帮助?问题是设置方向并不是告诉对象该做什么(如果对象不是方向)。那个这实际上是个问题。你不应该为对象设置方向,相反,你应该用他们的术语与他们交谈,比如
monster->attack()
camera->zoom()
。这与仅仅扩展方向类有什么不同?它更清楚地表达了想法。正如你所说,模特不是一种定位。我喜欢这个想法。通过继承,您不会与
orientation
类的所有内容相耦合,您可以正确地封装
orientation
类中所需的任何内容,然后通过继承这个中间类来重用这些封装的属性/方法(考虑到模型、地形、相机都使用来自
方向
对象的相同特征子集)我个人认为这只是作弊。当你做这种事情时,模式会动摇你。(我的意思是,如果你包装整个方向界面,不仅仅是
方向和方向()
函数)我倾向于此。其他人似乎同意你的答案。你能详细说明为什么这是最好的/首选的方法吗?1.很少或没有样板2.保持正确的is-a/has-a关系。3.习惯用语:不会让其他程序员感到困惑