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

C++中派生类存入基类IngameObject指针vector后类型异常问题

核心错误

你遇到的问题由三个错误共同导致:

  • 你自定义的instanceof是编译期静态类型判断,而非运行期实际对象类型判断。模板推导仅依赖输入参数的静态类型:存入vector前指针的静态类型是Character*,所以判断为真;存入vector后元素的静态类型是IngameObject*,模板推导的T就是IngameObject,std::is_base_of<Character, IngameObject>自然返回假,和指针实际指向的对象类型无关。
  • 子类Character重定义了和父类同名的clickable成员变量,属于名字隐藏,不是类成员重写。两个类的clickable是完全独立的两个变量,用父类指针访问时只会读取父类的clickable值,因此拿到的是默认的false。
  • 基类IngameObject没有定义虚函数,不满足C++运行期类型识别(RTTI)的要求,也会导致后续动态类型判断、内存释放时出现问题。

修复方案

1. 替换instanceof为运行期动态类型判断

用dynamic_cast实现运行期类型校验,要求基类为多态类型:

template<typename Derived, typename Base>
inline bool instanceof(const Base* ptr) {
    return dynamic_cast<const Derived*>(ptr) != nullptr;
}

2. 改造类结构,移除同名隐藏,给基类添加虚函数

给基类添加虚析构函数满足多态要求,子类构造时直接修改父类的clickable成员,不要重新定义同名变量:

class IngameObject
{
public:
    // 虚析构函数是多态类的标配,也能避免后续释放对象时内存泄漏
    virtual ~IngameObject() = default;
protected:
    bool clickable = false;
    // 新增构造函数供子类初始化父类成员
    IngameObject(bool clickable_) : clickable(clickable_) {}
};

class Character : public IngameObject
{
public:
    // 你的原有构造参数后面加初始化列表,给父类传clickable=true
    Character(/* 原有参数:纹理、矩形、坐标等 */) : IngameObject(true) {
        // 原有构造逻辑不变
    }
};

3. 确认编译选项开启RTTI

绝大多数桌面端编译器默认开启RTTI支持,若为嵌入式编译环境可手动开启对应编译选项。

修复后你再运行测试代码,两次instanceof判断都会返回真,clickable的值也会符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:54:05