[英]Multiple inheritance, or something else?
假设我有以下继承树:
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*/
}
任何帮助深表感谢!
(顺便说一句:这是一个学校项目,并且向我们建议了这样的继承树。没有人阻止我们做得更好和更好。这就是为什么我问这个问题。)
教科书解决方案涉及多重继承和虚拟继承。
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 };
通常,碰撞的东西是使用多次调度完成的,或者在C ++中使用访问者模式来完成,而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*);
}
这也将起作用,并且不需要多次调度或多重继承
您需要指定用逗号分隔的超类列表:
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/
您不需要继承就可以组合不相关的内容。 组成用于游戏逻辑,物理,声音,输入,图形(可能使用继承)的基本对象(实体?),然后将这些对象组合在一起,该GameObject仅包含所述对象的数组。
一些漂亮的交叉链接很有用,因为它们都共享一个Frame或Transform,但是可以在创建过程中通过遍历所有其他对象并使用dynamic_cast来完成...(如果不需要依赖初始化顺序,则很有用) 。
但是,实际上没有必要使用继承来构建它。 它不适合您的用例。 (尽管虚拟继承很有用,但是使用继承来迫使不同的事物成为同一事物不是一件好事,即使所有事物成为事物,而不是由不同的部分(渲染,损坏,声音等)组成。 )。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.