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

如何通过std::deque<CObject*>修改不同派生类元素的属性?

解决方法:正确访问派生类属性并修改HP

嘿,我来帮你搞定这个问题!你现在卡壳的点在于:虽然用typeid判断出了元素是CBullet类型,但容器里存的是CObject*基类指针,编译器没法直接识别它实际指向的是CBullet对象,自然就不能直接访问damage属性。下面给你两种实用的解决方案:

方案一:用dynamic_cast做安全类型转换

这是C++里处理多态类型转换的标准操作,它会在运行时检查指针的实际类型,转换成功返回有效指针,失败则返回nullptr。修改你的循环代码如下:

for(size_t i = 0; i < game->Mapa->obiekty.size(); ++i){
    // 尝试将基类指针转换为CBullet指针
    CBullet* bullet = dynamic_cast<CBullet*>(game->Mapa->obiekty[i]);
    if(bullet != nullptr){ // 转换成功,说明当前元素是CBullet(或其派生类)
        this->HP -= bullet->damage;
    }
}

关键注意事项:

你的基类CObject必须包含至少一个虚函数(比如虚析构函数virtual ~CObject() = default;),否则dynamic_cast无法工作——因为运行时类型信息(RTTI)依赖虚函数表来实现。

方案二:用虚函数重构,更符合面向对象设计

如果场景允许,推荐用虚函数替代手动类型判断,代码会更简洁、扩展性更强。具体步骤如下:

  1. 先修改基类CObject,添加虚函数(必须加虚析构避免内存泄漏):
class CObject {
public:
    virtual ~CObject() = default;
    // 定义虚函数,参数是你的HP所属类(假设为CEntity)
    virtual void applyDamageTo(class CEntity& target) {}
};
  1. 在CBullet中重写这个虚函数,实现伤害逻辑:
class CBullet : public CObject {
public:
    int damage;
    void applyDamageTo(CEntity& target) override {
        target.HP -= this->damage;
    }
};
  1. 最后你的循环可以大幅简化,完全不需要手动判断类型:
for(auto obj : game->Mapa->obiekty){
    obj->applyDamageTo(*this); // 直接调用虚函数,编译器会自动匹配对应派生类的实现
}

这种方法的优势很明显:以后如果新增其他带伤害的类型(比如CExplosion),只需要在新类里重写applyDamageTo函数就行,不用修改循环代码,扩展性拉满~

内容的提问来源于stack exchange,提问作者supermario

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:53:59