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

C++中如何将一个shared_ptr的引用赋值给另一个shared_ptr

问题分析

你出现错误的核心原因是对std::shared_ptr的类型语义理解偏差,原有代码里的EntityList**是指向原始指针变量的二级指针,而你错误地嵌套了shared_ptr类型、混淆了shared_ptr对象本身地址和它管理的裸指针地址的区别:

  • std::shared_ptr<EntityList_ptr>是共享指针指向另一个共享指针对象的用法,完全不符合你的需求,且把栈上shared_ptr变量的地址赋值给它会触发栈内存非法释放,直接崩溃
  • .get()接口返回的是被管理的EntityList对象的裸指针EntityList*,和shared_ptr变量本身的地址是完全不同的两个值,类型也不匹配
  • 最后一行强制转换为std::shared_ptr<Entity>属于类型不匹配,必然编译失败
正确实现方案

根据你使用list变量的实际需求,有两种合法实现:

场景1:仅需要拿到对应列表的共享使用权(90%以上场景的需求)

不需要用到二级指针,直接拷贝shared_ptr即可,拷贝操作会自动增加引用计数,共享对象所有权:

void setList(int type) {
    EntityList_ptr list;
    if (type == 0) {
        list = typeZeroList;
    } else if (type == 1) {
        list = typeOneList;
    } else if (type == 2) {
        list = typeTwoList;
    } else {
        list = typeThreeList;
    }
    // 后续直接使用list即可,离开作用域会自动减少引用计数
}

还可以简化代码避免多分支判断:

// 提前构建类型到列表的映射数组
EntityList_ptr typeLists[] = {typeZeroList, typeOneList, typeTwoList, typeThreeList};
// 取值前校验type范围防止越界
int validType = std::max(0, std::min(3, type));
EntityList_ptr list = typeLists[validType];

场景2:需要修改原有typeXXXList变量本身的指向

如果你的逻辑需要修改全局/外部的typeZeroList等变量本身的指向,才需要用到指向shared_ptr的指针,类型直接声明为EntityList_ptr*即可:

void setList(int type) {
    EntityList_ptr* list = nullptr;
    if (type == 0) {
        list = &typeZeroList;
    } else if (type == 1) {
        list = &typeOneList;
    } else if (type == 2) {
        list = &typeTwoList;
    } else {
        list = &typeThreeList;
    }
    // 后续修改原变量的写法:*list = 新的EntityList_ptr实例;
}
核心原理说明
  • EntityList_ptr本质是std::shared_ptr<Entity>类型的栈对象,不是原始指针,指向这个对象的指针类型就是EntityList_ptr*,不需要嵌套shared_ptr
  • shared_ptr的拷贝语义就是共享对象所有权,引用计数自动增减,没有额外性能损耗,大部分场景直接拷贝使用即可,不需要用指针指向shared_ptr本身
  • 不要把栈内存地址(比如局部shared_ptr变量的地址)交给shared_ptr管理,shared_ptr析构时会尝试释放内存,栈内存无法被释放,会直接触发程序崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:39:02