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

不修改引擎代码前提下替代dynamic_cast判断HitActor类型的方案

不使用dynamic_cast判断命中Actor类型的实现方案

前提:完全不修改引擎代码,仅在业务层实现判断逻辑。

方案1:使用typeid运算符(依赖RTTI)

利用C++ RTTI特性的typeid运算符,可以直接获取多态对象的动态类型,和Person类的类型做对比即可完成判断。由于引擎提供的Actor类存在虚析构函数,属于多态类型,可直接使用该方案。

实现代码

#include <typeinfo>

// 替换原有dynamic_cast判断逻辑
Actor* hitActor = hr.GetHitActor();
if (hitActor != nullptr && typeid(*hitActor) == typeid(Person)) {
    // 类型确认后可安全使用static_cast转换
    Person* HitPlayer = static_cast<Person*>(hitActor);
    cout << "Player hit!" << endl;
} else {
    cout << "Person not hit!" << endl;
}

优缺点

  • 优点:实现简单,无额外维护成本,和dynamic_cast逻辑接近
  • 缺点:依赖RTTI开启(部分游戏引擎默认关闭RTTI);仅能精确匹配类型,如果存在继承自Person的子类,该方案会将子类实例判定为非Person类型,无法匹配多态继承场景。

方案2:全局实例注册表(不依赖RTTI)

如果引擎关闭了RTTI,可在业务层维护一个全局的存活Person实例指针集合,创建Person实例时注册到集合,销毁时从集合移除,判断时直接查询命中的Actor指针是否在集合中即可。

实现代码

#include <unordered_set>

// 业务层全局注册表,存储所有存活的Person实例指针
std::unordered_set<Actor*> g_alivePersonSet;

// 封装Person创建逻辑,自动注册
Person* CreatePerson(const std::string& name) {
    Person* person = new Person(name);
    g_alivePersonSet.insert(person);
    return person;
}

// 封装Person销毁逻辑,自动注销
void DestroyPerson(Person* person) {
    g_alivePersonSet.erase(person);
    delete person;
}

// 命中判断逻辑
Actor* hitActor = hr.GetHitActor();
if (hitActor != nullptr && g_alivePersonSet.count(hitActor)) {
    Person* HitPlayer = static_cast<Person*>(hitActor);
    cout << "Player hit!" << endl;
} else {
    cout << "Person not hit!" << endl;
}

// main函数中创建实例改用封装接口:
Person* player1 = CreatePerson("Bob");
Person* player2 = CreatePerson("Phil");
// 销毁实例改用封装接口:
DestroyPerson(player1);
DestroyPerson(player2);

优缺点

  • 优点:完全不依赖RTTI,查询性能远高于dynamic_cast和typeid,适合高频调用的光线追踪命中判断场景;支持Person派生类的判断,只要子类实例创建时注册到集合即可。
  • 缺点:需要确保所有Person实例的创建和销毁都走封装接口,若引擎内部会自行创建Person实例,该方案无法捕获到这部分实例,会出现判断误差;需要额外维护实例生命周期,操作不当可能出现野指针误判。

方案选择建议

  • 如果项目开启了RTTI,且Person类没有自定义派生类,优先使用typeid方案
  • 如果项目关闭了RTTI,且所有Person实例都由业务层代码创建,优先使用全局注册表方案
  • 无特殊限制的情况下,原生dynamic_cast本身就是最安全的多态类型判断方案,支持继承匹配,无需额外维护逻辑,不需要刻意替换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 16:45:02