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_ptrshared_ptr的拷贝语义就是共享对象所有权,引用计数自动增减,没有额外性能损耗,大部分场景直接拷贝使用即可,不需要用指针指向shared_ptr本身- 不要把栈内存地址(比如局部
shared_ptr变量的地址)交给shared_ptr管理,shared_ptr析构时会尝试释放内存,栈内存无法被释放,会直接触发程序崩溃
内容的提问来源于stack exchange,提问作者didjek
相关产品推荐
相关产品推荐

