简体   繁体   中英

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. 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 :  Bullet {
  void draw() {/*draw me using SDL*/};
};

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

class SDLEnemyBullet :  SDLBullet,  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.

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/

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.

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).

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. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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