shared_ptr::get() 是唯一安全获取原始指针的方式,返回底层 t*(空时为 nullptr),不增引用计数;仅用于观察或传参,不可 delete 或构造新智能指针,且需配合 lock() 确保生命周期。

shared_ptr::get() 是唯一安全获取原始指针的方式
直接访问 shared_ptr 管理的对象地址,只能用 get() 成员函数。它返回的是底层 raw pointer,不增加引用计数,也不影响生命周期管理——这点必须清楚,否则容易误以为拿到指针就能“自由操作”。
常见错误是试图用解引用后取地址:&*ptr,这在对象被 move 或临时对象场景下可能触发未定义行为(比如 std::make_shared<t>()->get()</t> 比 &*std::make_shared<t>()</t> 更可靠)。
-
get()返回T*,空shared_ptr时返回nullptr - 不能用
get()构造新shared_ptr(会重复管理同一块内存) - 拿到的指针仅作观察或传参用途;绝不可
delete或用于构造其他智能指针
什么时候不该用 get()?
当需要延长对象生命周期、或确保对象在某段代码中不被释放时,get() 无法提供保障——它只给地址,不保存活。典型误用场景:
- 把
get()结果存入裸指针变量,后续再用——若原shared_ptr已销毁,该指针立即悬空 - 传给 C 接口后,在回调里缓存该指针并异步使用——没绑定生命周期,极大概率 crash
- 和
weak_ptr::lock()混用错误:先lock()得到临时shared_ptr,再对它调get(),但临时对象一出作用域就释放,指针失效
替代方案:用 lock() + get() 组合保安全
如果必须传递原始指针且需确保对象存活到某操作结束,正确做法是把 weak_ptr 转成临时 shared_ptr,再调 get():
if (auto sp = weak_ptr.lock()) {
some_c_api(sp.get()); // sp 存活期覆盖本次调用
}
这样既拿到原始指针,又绑定了生命周期。注意不能写成 weak_ptr.lock().get()——临时 shared_ptr 在表达式结束就被析构,get() 返回的指针立刻悬空。
-
lock()失败返回空shared_ptr,get()返回nullptr,需判空 - 不要为省一行代码跳过
if检查,C API 通常不处理 null - 若 C 接口要求长期持有指针,应改用
shared_ptr成员变量或全局生命周期管理
性能与 ABI 兼容性注意点
get() 是零开销操作,编译器通常内联,但它的“安全”完全依赖程序员自律。跨 DLL 边界传递 shared_ptr 管理的对象原始指针尤其危险:
- 不同模块可能用不同 STL 实现(如 MSVC 的
_VARIADIC_MAX设置不同),导致shared_ptr内存布局不兼容 - 即使同编译器,若 DLL 和 EXE 链接方式不同(/MD vs /MT),
shared_ptr的控制块分配/释放可能跨堆失败 - 此时更稳妥的做法是暴露 C 风格接口(如
create_obj()/destroy_obj()),彻底避免智能指针跨边界
真正难的不是怎么取指针,而是想清楚:这个指针到底归谁管、能活多久、谁负责释放。一旦脱离 shared_ptr 的管理上下文,所有“取出来用一下”的念头都得打个问号。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











