面试题答案
一键面试1. 菱形继承问题及解决方案
在游戏开发的角色属性继承体系中,假设存在一个基础类 Character
,有两个中间类 Warrior
和 Mage
继承自 Character
,然后有一个 WarriorMage
类多重继承自 Warrior
和 Mage
。这就形成了菱形继承结构。
菱形继承问题:如果 Character
中有一些属性或方法,在 WarriorMage
中会出现两份 Character
的副本,导致数据冗余和访问歧义。
解决方案 - 虚继承:在 Warrior
和 Mage
继承 Character
时使用虚继承。例如:
class Character {
public:
int health;
};
class Warrior : virtual public Character {
public:
int strength;
};
class Mage : virtual public Character {
public:
int intelligence;
};
class WarriorMage : public Warrior, public Mage {
public:
int uniqueSkill;
};
这样,WarriorMage
中只会有一份 Character
的副本,避免了数据冗余和访问歧义。
2. 性能开销问题及处理
性能开销:虚继承会带来一定的性能开销,因为需要额外的指针(虚基表指针)来指向虚基类的共享副本。在频繁创建和销毁对象的场景下,这可能会影响性能。
处理方式:
- 权衡使用场景:如果在游戏中某个角色继承体系的对象创建和销毁频率不高,虚继承带来的性能开销在可接受范围内。例如一些大型 BOSS 角色,其创建和销毁相对较少,使用虚继承来解决菱形继承问题更为重要。
- 优化设计:尽量减少不必要的虚继承。如果某个继承关系不会形成菱形继承,可以不使用虚继承。例如,若有一个
Archer
类只继承自Character
,不涉及多重继承导致的菱形结构,就不需要虚继承。
3. 整体类继承体系设计
- 明确层次结构:在游戏角色属性继承体系中,先确定核心的基础类,如
Character
类,定义通用的属性(如生命值、魔法值等)和行为(如移动、攻击等基础方法)。 - 中间层继承:根据角色类型划分中间层类,如
Warrior
、Mage
、Archer
等。这些类继承Character
,并添加各自类型特有的属性和行为。例如Warrior
类添加力量属性和近战攻击方法,Mage
类添加智力属性和魔法攻击方法。 - 多重继承的运用:对于复合型角色,如
WarriorMage
,通过多重继承获取不同类型角色的属性和能力。但要注意使用虚继承解决菱形继承问题。 - 接口类的使用:为了提高代码的可维护性和扩展性,可以引入接口类。例如定义一个
ISkill
接口类,然后让不同的技能类(如战士的挥砍技能类、法师的火球术技能类)继承该接口类。这样在角色类中可以通过持有ISkill
指针来实现技能系统,使得技能的添加和修改更加灵活。