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
数据成员移动到CObject
class。
您需要将指针转换为指针类型 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
的子类型,它将通过,而您的测试将检查是否完全匹配。
我有两个 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
数据成员移动到CObject
class。
您需要将指针转换为指针类型 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
的子类型,它将通过,而您的测试将检查是否完全匹配。