Множественное наследование или что-то еще? - PullRequest
1 голос
/ 14 декабря 2011

Предположим, у меня есть следующее дерево наследования:

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

Теперь мне нужен новый класс, SDLEnemyBullet, для которого требуется отрисовка, реализованная в SDLBullet, и коллизия, реализованная в EnemyBullet.Как бы я это сделал?Это должно быть решено с использованием множественного наследования?Если нет, не стесняйтесь редактировать мой вопрос и заголовок.Если так, как бы я реализовал такую ​​вещь?

Некоторые примеры кода ниже:

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*/
}

Любая помощь очень ценится!

(Кстати: это школьный проекти нам было предложено такое дерево наследования. Никто не мешает нам делать это иначе и лучше. Вот почему я задал вопрос.)

Ответы [ 4 ]

3 голосов
/ 14 декабря 2011

Учебное решение включает в себя множественное и виртуальное наследование.

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

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

class SDLEnemyBullet : <b>public</b> SDLBullet, <b>public</b> EnemyBullet {
  // just one Bullet subobject here
};
2 голосов
/ 14 декабря 2011

Вам нужно указать список суперклассов через запятую:

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*/
}

Похоже, вы создаете игру (движок).Чтобы избежать необходимости в сложных структурах наследования, подобных этой, предпочтение композиции по сравнению с наследованием для сущностей, т. Е. Имеет объектный объект, который содержит отдельные «компонентные» объекты для рендеринга и т. Д. Таким образом, вы можете смешивать и сопоставлять компоненты так, как вам нравится, без взрыва классовсо всеми различными комбинациями суперклассов.

Вот хорошая статья на эту тему: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

2 голосов
/ 14 декабря 2011

Обычно, коллизии выполняются с использованием множественной диспетчеризации, или в C ++, у которого нет этой функции, с использованием шаблона посетителя.

НО

почему бы вам не использовать подобную иерархию?

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*);
}

Это бы тоже сработало, и не требовало бы многократной отправки или множественного наследования

1 голос
/ 14 декабря 2011

Предпочитаю композицию наследованию

Вам не нужно наследование, чтобы объединять вещи, которые не связаны между собой. Составьте базовые объекты (сущности?) Для игровой логики, физики, звука, ввода, графики (которые могут использовать наследование) и объедините те объекты GameObject, у которых есть только массив упомянутых объектов.

Некоторые изящные перекрестные ссылки полезны, поскольку все они будут совместно использовать Frame или Transform, но это можно сделать во время создания, перебирая все другие объекты и используя dynamic_cast ... (это полезно, если вам не нужно зависеть от порядок инициализации).

Но на самом деле нет необходимости строить это с наследованием. Это не подходит для вашего использования правильно. (Хотя виртуальное наследование полезно, но не стоит использовать наследование, чтобы заставить разные вещи становиться одинаковыми, то есть все быть чем-то , а не состоять из разных частей (рендеринг, повреждение, звук и т.д ...).

Прочитайте , это и , это для получения дополнительной информации, или просто нажмите на название, чтобы найти его в Google. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...