如何通过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)依赖虚函数表来实现。
方案二:用虚函数重构,更符合面向对象设计
如果场景允许,推荐用虚函数替代手动类型判断,代码会更简洁、扩展性更强。具体步骤如下:
- 先修改基类
CObject,添加虚函数(必须加虚析构避免内存泄漏):
class CObject { public: virtual ~CObject() = default; // 定义虚函数,参数是你的HP所属类(假设为CEntity) virtual void applyDamageTo(class CEntity& target) {} };
- 在
CBullet中重写这个虚函数,实现伤害逻辑:
class CBullet : public CObject { public: int damage; void applyDamageTo(CEntity& target) override { target.HP -= this->damage; } };
- 最后你的循环可以大幅简化,完全不需要手动判断类型:
for(auto obj : game->Mapa->obiekty){ obj->applyDamageTo(*this); // 直接调用虚函数,编译器会自动匹配对应派生类的实现 }
这种方法的优势很明显:以后如果新增其他带伤害的类型(比如CExplosion),只需要在新类里重写applyDamageTo函数就行,不用修改循环代码,扩展性拉满~
内容的提问来源于stack exchange,提问作者supermario
相关产品推荐
相关产品推荐

