简体   繁体   English

C ++多重继承设计问题

[英]C++ Multiple Inheritance Design Issue

I'm having doubts on how to proceed regarding the class structure of my game/simulation framework. 我对如何进行游戏/模拟框架的类结构有疑问。 Please note that I am doing this mostly for my own enjoyment, I know there are lots of good solutions already out there :) 请注意,我这样做主要是出于我自己的享受,我知道已经有很多好的解决方案了:)

The structure of the framework has, among other things, Scene s that contain Actor s. 框架的结构除其他外具有包含ActorScene Both Scene s and Actor s can behave in many different ways WRT some aspects of how stuff works internally. SceneActor都可以以多种不同的方式表现WRT内部工作原理的某些方面。 I have implemented such behaviours using multiple inheritance, like so: 我已经使用多重继承实现了这种行为,如下所示:

class ActorBase : public Object { ... }; 
class Actor : virtual public ActorBase { ... };
class CollisionBehavior : virtual public ActorBase { ... }; 
class BoundingBoxCollisionBehavior : public CollisionBehavior { ... };
class MyActor : public Actor, public BoundingBoxCollisionBehavior { ... };

This way, using virtual inheritance, I can separate the implementation of what the actor is from the implementation of what the actor does (or how it does it). 这样,通过使用虚拟继承,我可以将actor是什么的实现与actor所做的事情(或其实现方式)的实现分开。 Both the Actor and ...Behavior classes need access to the common base class ActorBase for their implementation, but things are neatly compartmentalised and I can easily change the behaviour of an object by simply replacing the Behavior class it inherits from. Actor...Behavior类都需要访问公共基类ActorBase来实现,但是事情被巧妙地分隔开了,我可以通过简单地替换其继承的Behavior类来轻松更改对象的Behavior

This has its limitation though: since each behaviour follows its own internal rules, and an object can inherit from a single Behavior (or else hell breaks loose because of ambiguous function calls etc), I can never have two actors with different behaviours interact with each other. 但是,这有其局限性:由于每个行为都遵循其自己的内部规则,并且一个对象可以从单个Behavior继承(否则地狱会由于函数调用不明确等原因而松散),所以我永远不会有两个行为不同的参与者相互影响其他。 Also, since I'm integrating the V8 Javascript Engine into the framework, I'd have to create wrapped child classes for each possible combination of Actor (or Scene ) and their possible behaviours, and instancing these object in a mixed fashion from JS would result in a crash because, again, two object that behave differently cannot interact with each other (at least not for everything). 另外,由于我将V8 Javascript Engine集成到框架中,因此我必须为Actor (或Scene )及其可能的行为的每种可能的组合创建包装的子类,并以混合方式从JS实例化这些对象,导致崩溃,因为同样,行为不同的两个对象不能互相交互(至少不是所有对象都不能交互)。

An alternative solution I thought would be to abandon this multiple inheritance structure in favour of something like this: each object that requires Behavior s has many arrays, one for each Behavior group (like collision behavior, movement behavior, etc), with a ...Behavior object for each possible behavior. 我想到的另一种解决方案是放弃这种多重继承结构,而采用类似这样的方法:每个需要Behavior的对象都有许多数组,每个Behavior组具有一个数组(如碰撞行为,运动行为等),并带有...Behavior对象的每种可能的行为。 I can give an object a default behavior and, if it's ever needed (an interaction occurs with an object with a different default behavior), I can add such behavior to one (or both) objects so that they can interact with each other - there would need to be some sort of conversion policy, but thats not an issue. 我可以为对象提供默认行为,如果需要的话(与具有不同默认行为的对象发生交互),我可以将这种行为添加到一个(或两个)对象中,以便它们可以彼此交互。需要某种转换政策,但这不是问题。 This would mean having a circular reference (the object instance references the behavior instance and the behavior instance references the object it's contained in) for the behavior to be able to access the base properties it needs to do its own thing. 这意味着要拥有一个循环引用(对象实例引用行为实例,行为实例引用其所包含的对象),以便该行为能够访问其做自己的事情所需的基本属性。 The Behavior subclasses would also need to be friend s with the Actor class, to access protected and/or private members. Behavior子类还需要与Actor类成为friend ,以访问受保护的成员和/或私有成员。 I'm don't really like this road that much, and I think there might be a more elegant way to solve this problem, I just haven't thought of one yet. 我不太喜欢这条路,并且我认为可能有一种更优雅的方式来解决此问题,我只是还没有想到。

Thoughts? 有什么想法吗? :) :)

Bonus Question: should I spell Behavior or BehavioUr? 奖励问题:我应该拼写“行为”还是“行为”? Not a native speaker! 不是母语!

EDIT: Solved the bonus question - depends or where you feel you are when on the Internet! 编辑:解决了奖金问题-取决于或您在Internet上的感觉! :) :)

EDIT 2: Changed from Behavior to CollisionBehavior for clarity (see answer below) 编辑2:为清楚起见,从“ Behavior更改为CollisionBehavior (请参阅下面的答案)

I am afraid you are mixing things here. 恐怕您在这里混混东西。 As you noted there are many different kinds of behaviors 1 : 如您所述,有许多不同种类的行为1

  • walking behavior 步行行为
  • talking behavior 说话行为
  • fighting behavior 战斗行为
  • ... ...

And of course it makes no sense to have a WalkingBehavior compare to a FightingBehavior so it makes no sense to have them share a base class either. 当然,将WalkingBehaviorFightingBehavior进行比较是没有意义的,因此让它们共享基类也没有任何意义。

As such, I think that you should just use Actors and provide methods to retrieve the behaviors on those: 因此,我认为您应该只使用Actors并提供检索这些行为的方法:

class Actor {
public:
    virtual WalkingBehavior const& walkingBehavior() const {
        return DefaultWalkingBehavior;
    }

    virtual FightingBehavior const& fightingBehavior() const {
        return DefaultFightingBehavior;
    }

    // ...
}; // class Actor

Where the default behavior is defined in such a way that it can interact with a more regular behavior of its class. 默认行为的定义方式是,它可以与类的更常规行为进行交互。 Then, each specific interface such as FightingBehavior should provide the necessary methods to understand this behavior. 然后,每个特定的接口(例如FightingBehavior都应提供必要的方法来理解此行为。

Note that this method of encoding information is extremely versatile: you can mix behaviors that are determined at compile-time and behaviors that are determined at run-time (and may evolve at run-time) without any incidence on the clients. 请注意,这种编码信息的方法非常通用:您可以混合在编译时确定的行为和在运行时确定的行为(并且可能在运行时演变),而不会对客户端造成任何影响。

1 Personally I just follow my built-in browser spell-checker. 1就我个人而言,我只是遵循内置的浏览器拼写检查器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM