C++类继承

C++ classes inheritance

我有两个 classes:

class CEnemy : CObject
{
protected:
    int hitPoints;
};
class COgro : public CEnemy
{
    COgro::COgro() {hitPoints = 100}
};

在其他文件中我有class 'CRocket',它可以与COgro碰撞,有它的功能:

void CRocket::OnCollision(CObject *collisionObject)
{
    if (typeid(*collisionObject) == typeid(COgro))
    {
        //collisionObject->hitPoints -= 10; ?? or what?
    }
}

我想在食人魔死前对它射击 10 次。这个怎么做? 我已经试过了:

     collisionObject->hitPoints -= 10;
     (CEnemy)collisionObject->hitPoints -= 10;

但我无法编译它...如何编辑此 hitPoints 值,但不更改“(CObject *collisionObject)”? 感谢

编辑:

//===============================================================

//------------------------------------CLASS CRocket-----------------------
class CRocket : public CObject
{
protected:
    void OnAnimate(scalar_t deltaTime);
    void OnCollision(CObject *collisionObject);
    void OnDraw(CCamera *camera);

public:

    float pitch;
    float distanceTravel;   
    CVector forward;        
    bool isExplosion;

    CTexture *explosionTex;
    CExplosion *explosion;

    CRocket();
    ~CRocket();

    void Load();
    void Unload();

};
void CRocket::OnCollision(CObject *collisionObject)
{
        if (typeid(*collisionObject) == typeid(COgroEnemy))
        {
            isExplosion = true;
            velocity = CVector(0.0, 0.0, 0.0);
            explosion = new CExplosion(500, position, 8.0, explosionTex->texID);
            PlaySound();
        }
}

//-----------------------------------------class CObject
class CObject : public CNode
{
protected:
    virtual void OnAnimate(scalar_t deltaTime)
    {
        position += velocity * deltaTime;
        velocity += acceleration * deltaTime;
    }
    virtual void OnDraw(CCamera *camera) {}
    virtual void OnCollision(CObject *collisionObject) {}

    virtual void OnPrepare()
    {
        ProcessCollisions(FindRoot());
    }

public:
    CVector position;
    CVector velocity;
    CVector acceleration;
    scalar_t size;

    bool isDead;

    CObject() {isDead = false;}
    ~CObject() {}
...
...
...
}

//---------------------------------------class CEnemy 
class CEnemy : public CObject
{
public:
    int hitPoints;
protected:

    float distFromPlayer;
    float runSpeed;
    AIState_t aiState;

    virtual void OnProcessAI() {}
    void OnCollision(CObject *collisionObject)
    {
          // if this enemy collides with another enemy
          if (typeid(*collisionObject) == typeid(CEnemy))
          {
               modelState = MODEL_IDLE;
               velocity = CVector(0.0, 0.0, 0.0);
          }
          // if this enemy collides with the terrain (always)
          else if (typeid(*collisionObject) == typeid(CTerrain))
          {
               position.y = ((CTerrain*)collisionObject)->GetHeight(position.x, position.z) + size;
          }
          else
          {
          }
     }

public:
    CPlayer *player;
...
...

//----------------------------------class COgro-------------------------
class COgroEnemy : public CEnemy
{
protected:
    void OnProcessAI();
    void OnCollision(CObject *collisionObject);
    void OnPrepare();

public:
    COgroEnemy() { Load(); }
    COgroEnemy(float x, float z) { position.x = x; position.z = z; Load(); }
    ~COgroEnemy() {}

    void Load();
};

您的代码没有编译,因为您试图从外部源访问 class 的受保护数据成员。

collisionObject 参数是 CObject 的实例,它没有 hitPoints 数据成员。

此外,当您将指向基 classes 的指针传递给函数时,函数应该假定它们只能访问基 class 的接口或功能。

你应该再写一个重载方法:

void CRocket::OnCollision(CEnemy& enemy);

或者将hitPoints数据成员移动到CObjectclass。

您需要将指针转换为指针类型 CEnemy*(或子类),或将取消引用的指针转换为引用类型 CEnemy&。为了最大程度的安全,我建议 dynamic_cast,而不是邪恶的 C 风格转换;虽然这有点偏执,因为你在投射前检查类型。

// no checks, undefined behaviour if type is wrong
((CEnemy*)collisionObject)->hitPoints -= 10;
static_cast<CEnemy*>(collisionObject)->hitPoints -= 10;

// throws if type is wrong
dynamic_cast<CEnemy&>(*collisionObject).hitPoints -= 10;

// does nothing if type is wrong
if (CEnemy* enemy = dynamic_cast<CEnemy*>(collisionObject)) {
    enemy->hitPoints -= 10;
}

您可以将其与类型检查结合使用,而不是使用 typeid:

if (COgro * ogro = dynamic_cast<COgro*>(collisionObject)) {
    ogro->hitPoints -= 10;
}

请注意,这与您的测试不完全相同:如果对象是 COgro 的子类型,它将通过,而您的测试将检查是否完全匹配。