我对如何进行游戏/模拟框架的类结构有疑问。请注意,我这样做主要是出于我自己的享受,我知道已经有很多好的解决方案了:)
框架的结构除其他外,还包含包含Scene
的Actor
。 Scene
和Actor
可以以多种不同的方式表现WRT内部工作原理的某些方面。我已经使用多重继承实现了这种行为,如下所示:
class ActorBase : public Object { ... };
class Actor : virtual public ActorBase { ... };
class CollisionBehavior : virtual public ActorBase { ... };
class BoundingBoxCollisionBehavior : public CollisionBehavior { ... };
class MyActor : public Actor, public BoundingBoxCollisionBehavior { ... };
这样,通过使用虚拟继承,我可以将actor是什么的实现与actor所做的事情(或其实现方式)的实现分开。
Actor
和...Behavior
类都需要访问公共基类ActorBase
来实现,但是事情被整齐地分隔开了,我可以通过简单地替换其继承的Behavior
类来轻松更改对象的行为。 。但是,这有其局限性:由于每种行为都遵循其自己的内部规则,并且一个对象可以从单个
Behavior
继承(否则地狱会由于函数调用不明确等原因而松散),因此我永远无法让两个行为不同的参与者进行交互彼此。另外,由于我将V8 Javascript Engine集成到框架中,因此必须为Actor
(或Scene
)及其可能的行为的每种可能组合创建包装的子类,并将这些对象实例化为混合形式JS的流行将导致崩溃,因为同样,两个行为不同的对象无法相互交互(至少不是所有对象都可以交互)。我认为另一种解决方案是放弃这种多重继承结构,而采用类似这样的方法:每个需要
Behavior
的对象都有许多数组,每个Behavior
组一个数组(例如碰撞行为,移动行为等),每个可能的行为都有一个...Behavior
对象。我可以为对象提供默认行为,如果需要的话(与具有不同默认行为的对象发生交互),我可以将这种行为添加到一个(或两个)对象中,以便它们可以彼此交互。需要某种转换政策,但这不是问题。这意味着要拥有一个循环引用(对象实例引用行为实例,行为实例引用其所包含的对象),以便该行为能够访问其做自己的事情所需的基本属性。 Behavior
子类也必须是friend
的Actor
类,才能访问受保护的成员和/或私有成员。我不太喜欢这条路,我认为可能有一种更优雅的方式来解决此问题,我只是还没有想到。有什么想法吗? :)
奖励问题:我应该拼写“行为”还是“行为”?不是母语!
编辑:解决了奖金问题-取决于或您在Internet上的感觉! :)
编辑2:为清楚起见,从
Behavior
更改为CollisionBehavior
(请参见下面的答案) 最佳答案
恐怕你在这里混东西。如您所述,有许多不同种类的行为1:
步行行为
说话行为
战斗行为
...
当然,将WalkingBehavior
与FightingBehavior
进行比较没有任何意义,因此让它们共享基类也没有任何意义。
因此,我认为您应该只使用Actors并提供检索这些行为的方法:
class Actor {
public:
virtual WalkingBehavior const& walkingBehavior() const {
return DefaultWalkingBehavior;
}
virtual FightingBehavior const& fightingBehavior() const {
return DefaultFightingBehavior;
}
// ...
}; // class Actor
默认行为的定义方式是,它可以与类的更常规行为进行交互。然后,每个特定的接口(例如
FightingBehavior
)应提供必要的方法来理解此行为。请注意,这种编码信息的方法非常通用:您可以混合在编译时确定的行为和在运行时确定的行为(并且可能在运行时演变),而不会对客户端造成任何影响。
1就我个人而言,我只是遵循内置的浏览器拼写检查器。
关于c++ - C++多重继承设计问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17166525/