You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为同基类派生类实现碰撞检测:保护成员访问问题咨询

问题分析

你现在遇到的问题是:虽然Bullet和Zombie都继承自MovingObject,但Bullet无法直接访问Zombie对象的x、y成员——这是C++保护成员(protected)的访问规则导致的:派生类只能访问自身继承来的基类保护成员,不能访问另一个派生类对象的基类保护成员。也就是说,Bullet可以用this->x访问自己的位置,但不能直接用pZombie->x访问僵尸的位置,哪怕x是基类的protected成员。

不用getX()/getY()的解决方案

下面给你两种符合要求的实现方向,都是不用写单独的getter方法的:

方案1:让基类提供跨对象的距离计算方法

既然基类本身可以访问任意MovingObject对象的protected成员(因为这些成员属于基类自己),我们可以在MovingObject里添加一个保护成员函数,专门计算当前对象和另一个MovingObject的距离:

class MovingObject {
protected:
    double x;
    double y;
    double speed;
    double damage;
    // 原有的私有distance函数可以保留
    double distance(double x1, double y1, double x2, double y2) {
        return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
    }
    // 新增:计算当前对象和另一个MovingObject的距离
    double distanceTo(MovingObject* other) {
        return distance(x, y, other->x, other->y);
    }
public:
    MovingObject(double x, double y, double speed, double damage);
    virtual bool isCollide(MovingObject* Object);
    virtual void draw() {};
    virtual void move() {};
};

然后在Bullet的碰撞检测里,直接调用这个方法就可以了:

bool Bullet::isCollide(Zombie* pZombie) {
    if (distanceTo(pZombie) < 10) {
        pZombie->getHit();
        return true;
    } else {
        return false;
    }
}

这个方案既符合封装原则,又不用写单独的getter,是比较推荐的做法。

方案2:将派生类互相声明为友元(不推荐但可行)

如果你想更直接地访问对方的成员,可以在Zombie类里声明Bullet为友元,这样Bullet就能访问Zombie的所有成员(包括继承来的x、y):

class Zombie : public MovingObject {
    // 声明Bullet为友元
    friend class Bullet;
private:
    double hpMax;
    double hpCurrent;
    double attackCD;
    double attackRate;
public:
    // 构造函数和其他成员不变
    Zombie(double x, double y, double speed, double damage, double hpMax, double hpCurrent, double attackCD, double attackRate);
    bool isCollide(Bullet* pBullet);
    void draw();
    void move();
    void getHit();
    void drawHPBar();
    void decreaseAttackCD();
    void refreshAttackCD();
};

这样你的原代码就能直接访问pZombie->x和pZombie->y了。不过这种方法会破坏类的封装性,一旦后续修改类的成员,友元类的代码可能会受影响,所以只适合简单场景快速验证。

额外建议

作为刚接触OOP的新手,尽量优先选择方案1——通过基类提供公共/保护接口来实现跨对象的成员访问,这能更好地体现面向对象的封装思想,让代码更易维护。

内容的提问来源于stack exchange,提问作者İlker Zeybek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:12:47