-1

我正在开发一个有怪物和龙的游戏。龙可以做怪物能做的所有事情,除了它们也会喷火。

我已经创建了一个类型为“monster”的类和一个继承自名为“dragon”的怪物的类。

然后我有一个名为“monsters”的类,它作为私有成员向量,将包含龙和怪物元素。

在主游戏循环中,如果当前元素是龙,我需要循环遍历矢量并喷火,如果它只是怪物,则什么也不做。

我尝试过使用 typeid() 但无论当前元素是普通怪物还是龙,它总是返回 monster*。

有没有办法做到这一点,或者在这种情况下甚至使用继承没有意义?龙类不继承,而是独立于怪物独立存在是否更有意义?

任何建议表示赞赏。

4

5 回答 5

3

可以做这样的事情。

class Monster {};
class Dragon : public Monster
{
  public:
    void BlowFire() {}
}

std::vector<Monster*> monsters; // Collection of monsters

for(auto it = monsters.begin(); it != monsters.end(); ++it)
{
    Dragon* pDragon = dynamic_cast<Dragon*>(*it); // Attempt to convert pointer
    if(pDragon)
    {
       pDragon->BlowFire(); // If it is indeed a Dragon, blow fire.
    }
}

但听起来你应该更好地安排你的课程。你为什么不让你所有的怪物类都有一个Attack方法?这样,您可以覆盖每种不同怪物类型的方法。

class Monster 
{
  public:
    virtual void Attack() {} // All monsters can attack
};

class Dragon : public Monster
{
  public:
    virtual void Attack() { // Do something special for a Dragon. }      
};

Monster myMonster;
Dragon myDragon;
myMonster.Attack(); // Generic monster attack.
myDragon.Attack(); // Special super dragon fire attack!
于 2012-09-05T12:11:24.357 回答
1

并不是说这是最好的方法,但只是为了您的信息,如果您想要对象的运行时类型,您调用typeid指针不起作用。typeid 确实在需要时在运行时工作,但您需要取消引用指向多态类型的指针:

typeid(*monsterpointer)

这将获得运行时类型*monsterpointer,无论是 amonster还是dragon.

但是,typeid仅用于精确比较,因此如果添加另一个ImpairedDragon继承自的名为的类Dragontypeid代码将中断并且无法使用它们。因此,如果您能想到如何很好地使用一个虚函数,您可能应该使用dynamic_cast哪个与继承一起工作,或者甚至更好地使用一个虚函数。

于 2012-09-05T12:08:48.593 回答
1

有两种可能的方法:使用虚函数或使用dynamic_cast. 如果monster有一个什么都不做的虚函数blow_fire()dragon可以覆盖它来做任何适合龙的事情。然后你只需为所有monster对象调用它,龙就会喷火。使用dynamic_cast,代码将是这样的:

if (dragon *dragon_ptr = dynamic_cast<dragon*>(monster_ptr)) {
    dragon_ptr->blow_fire();
}

这通常被认为是一种不好的方法,因为它不会自然生长。如果您添加了另一种可以喷火的怪物,则必须添加另一种dynamic_cast. 使用虚函数,新类型只会覆盖虚函数。

于 2012-09-05T12:13:02.250 回答
1

如果你的容器中有怪物指针,那么公共怪物成员就是你能够以类型安全的方式通过这些指针访问的所有成员(据我的回忆)。您可能会尝试采用基于接口的设计(如 COM),以便您可以查询怪物基类的任何额外功能,即接口。我会为您提供样品,但我的午餐时间已经结束了。

于 2012-09-05T12:41:37.390 回答
-2

如何blowFire在基类中放置一个空(无操作)虚拟,然后在派生类中用某些东西覆盖它?

将方法重命名为或类似的通用名称会更好specialAttack,因此您不需要为其他类型的怪物添加类似的方法。

于 2012-09-05T12:11:46.857 回答