2015-01-06 3 views
0

У меня есть два класса:C++ классов наследования

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

и в другом файле у меня есть класс «Крокет», который может столкнуться с 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)? Thx

EDIT:

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

//------------------------------------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(); 
}; 
+1

'но я не могу его скомпилировать' Почему? – deviantfan

+0

Почему вы наследуете от 'CObject'? Вы портируете с Java? –

+1

Просьба показать больше кода вокруг заявлений о присваивании. Их местоположение имеет значение. (Например, член 'hitPoints' может быть доступен только внутри метода из класса, полученного из' CEnemy', из-за доступа 'protected'.) –

ответ

3

Вам нужно будет направить указатель на тип указателя 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, в то время как ваш тест проверяет точное соответствие.

0

Вы код не компиляции, потому что вы пытаетесь получить доступ к защищенным членам данных относится к классу от внешнего источника.

Параметр collisionObject - это пример CObject, в котором нет элемента данных hitPoints.

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

Вы должны написать еще один перегруженный метод:

void CRocket::OnCollision(CEnemy& enemy); 

Или переместить элемент hitPoints данных в CObject классе.

Смежные вопросы