简体   繁体   English

多重继承,还是其他?

[英]Multiple inheritance, or something else?

Suppose I have following inheritance tree: 假设我有以下继承树:

SDLBullet inherits from Bullet inherits from Entity
EnemyBullet inherits form Bullet inherits from Entity

Now I need a new class, SDLEnemyBullet, which needs the draw as implemented in SDLBullet, and the collision as implemented in EnemyBullet. 现在,我需要一个新类SDLEnemyBullet,该类需要在SDLBullet中实现的绘制以及在EnemyBullet中实现的碰撞。 How would I do this? 我该怎么做? Is this to be solved using multiple inheritance? 是否可以使用多重继承解决? If not, feel free to edit my question and title. 如果没有,请随时编辑我的问题和标题。 If so, how would I implement such thing? 如果是这样,我将如何实施?

Some code examples below: 以下是一些代码示例:

class Entity {
  bool collision(Entity) = 0;
  void draw() = 0;
}

class Bullet : Entity {
  bool collision(Entity) {/*some implementation*/};
  void draw() {/*draw me*/};
}

class SDLBullet : Bullet {
  void draw() {/*draw me using SDL*/};
}

class EnemyBullet : Bullet {
  bool collision(Entity) {/*if Entity is a fellow enemy, don't collide*/};
}

class SDLEnemyBullet : ????? {
  /*I need SDLBullet::draw() here*/
  /*I need EnemyBullet::collision(Entity) here*/
  /*I certainly do not want EnemyBullet::draw nor SDLBullet::collision here*/
}

Any help is much appreciated! 任何帮助深表感谢!

(BTW: This is a school project, and an inheritance tree like this was suggested to us. No one is stopping us from doing it different and better. Thats why I asked the question.) (顺便说一句:这是一个学校项目,并且向我们建议了这样的继承树。没有人阻止我们做得更好和更好。这就是为什么我问这个问题。)

The textbook solution involves multiple and virtual inheritance. 教科书解决方案涉及多重继承和虚拟继承。

class SDLBullet : public virtual Bullet {
  void draw() {/*draw me using SDL*/};
};

class EnemyBullet : public virtual Bullet {
  bool collision(Entity) {/*if Entity is a fellow enemy, don't collide*/};
};

class SDLEnemyBullet : public SDLBullet, public EnemyBullet {
  // just one Bullet subobject here
};

Normally, collision stuff is done using multiple dispatch, or in C++, who hasn't this feature, using the visitor pattern. 通常,碰撞的东西是使用多次调度完成的,或者在C ++中使用访问者模式来完成,而C ++没有此功能。

BUT

why don't you have a hierarchy like this instead ? 为什么您没有这样的层次结构呢?

class Entity;

class Bullet : public Entity
{
public:
 virtual draw();
}

class FriendlyBullet : public Bullet
{
public: 
bool collide(EnnemyBullet*);
bool collide(FriendlyBullet*);
}
class EnnemyBullet : public Bullet
{
public:
 bool collide(EnnemyBullet*);
bool collide(FriendlyBullet*);
}

This would work too, and wouldn't require multidispatch or multiple inheritance 这也将起作用,并且不需要多次调度或多重继承

You need to specify a comma separated list of the super classes: 您需要指定用逗号分隔的超类列表:

class SDLEnemyBullet : public SDLBullet, public EnemyBullet {
  /*I need SDLBullet::draw() here*/
  /*I need EnemyBullet::collision(Entity) here*/
  /*I certainly do not want EnemyBullet::draw nor SDLBullet::collision here*/
}

It looks like you're making a game (engine). 看来您正在制作游戏(引擎)。 To avoid the need for complex inheritance structures like this favor composition over inheritance for entities ie Have an entity object that contains separate 'component' objects for rendering etc. That way you can mix and match the components however you like without having an explosion of classes with all the different combinations of super classes. 为了避免像这样的复杂继承结构需要实体优先于实体继承,即拥有一个实体对象,该实体对象包含单独的“组件”对象以进行渲染等。这样,您可以随意混合和匹配组件,而无需增加类的数量与超类的所有不同组合。

Here's a good article on the subject: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ 这是一篇有关该主题的好文章: http : //cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

Prefer composition over inheritance 优先考虑组成而不是继承

You don't need inheritance to combine stuff that's not related like that. 您不需要继承就可以组合不相关的内容。 Make up basic objects (entities?) for game logic, physics, sound, input, graphics (which may use inheritance) and combine those a GameObject which just has an array of said objects. 组成用于游戏逻辑,物理,声音,输入,图形(可能使用继承)的基本对象(实体?),然后将这些对象组合在一起,该GameObject仅包含所述对象的数组。

Some nifty cross-linking is useful since they will all share a Frame or Transform, but that can be done during creation by iterating over all other objects and using dynamic_cast... (it's useful if you do not need to depend on initialization order). 一些漂亮的交叉链接很有用,因为它们都共享一个Frame或Transform,但是可以在创建过程中通过遍历所有其他对象并使用dynamic_cast来完成...(如果不需要依赖初始化顺序,则很有用) 。

But there's really no need to build this with inheritance. 但是,实际上没有必要使用继承来构建它。 It doesn't fit your usecase properly. 它不适合您的用例。 (Although virtual inheritance is useful, it's not a good thing to use inheritance to force different things to become the same, ie making everything be a something, instead of being made up of different parts (render, damage, sound, etc...). (尽管虚拟继承很有用,但是使用继承来迫使不同的事物成为同一事物不是一件好事,即使所有事物成为事物,而不是由不同的部分(渲染,损坏,声音等)组成。 )。

Read this and this for more info, or just click the title to google for it. 阅读更多的信息,或者直接点击标题,以谷歌为它。 :) :)

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

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