C++中基类shared_ptr向量无法赋值给子类向量?如何实现转换?
为什么直接赋值LootableCollection = ManyWhere("test","test");不行?
std::vector<std::shared_ptr<DatabaseModel>> 和 std::vector<std::shared_ptr<GameObjectTemplateModel>> 是完全独立的容器类型——哪怕GameObjectTemplateModel继承自DatabaseModel,C++也不会自动对容器做隐式转换。编译器无法保证每个基类指针都能安全转成子类指针,因此直接赋值会触发编译错误。
如何实现子类shared_ptr向量从基类向量获取数据?
你需要手动遍历基类向量,逐个将基类shared_ptr转换为子类类型后存入目标向量,代码示例如下:
// 获取基类指针向量 auto baseModels = ManyWhere("test", "test"); // 清空目标向量 LootableCollection.clear(); // 遍历并转换每个元素 for (const auto& basePtr : baseModels) { // 使用dynamic_pointer_cast尝试转换基类指针到子类 auto derivedPtr = std::dynamic_pointer_cast<GameObjectTemplateModel>(basePtr); if (derivedPtr) { // 检查转换是否成功 LootableCollection.push_back(derivedPtr); } else { // 处理转换失败的情况:比如打日志、跳过该元素或抛出异常 // std::cerr << "无法将DatabaseModel转换为GameObjectTemplateModel" << std::endl; } }
dynamic_cast是否是合理方案?
这是合理且安全的选择:
- dynamic_cast(对应智能指针的
std::dynamic_pointer_cast)会在运行时检查指针实际指向的对象类型,只有当基类指针确实指向GameObjectTemplateModel实例时,才会返回有效的子类shared_ptr;否则返回空指针,能避免非法类型转换导致的未定义行为。 - 如果你的业务逻辑能100%保证
ManyWhere返回的所有DatabaseModel都是GameObjectTemplateModel的实例,也可以用std::static_pointer_cast,但这种场景极少——一旦出现类型不匹配的实例,会直接导致程序崩溃,风险极高。因此优先推荐使用dynamic_cast。
内容的提问来源于stack exchange,提问作者Venelin
相关产品推荐
相关产品推荐

