在C++的智能指针体系中,weak_ptr是配合shared_ptr使用的弱引用指针,它本身不持有资源的所有权,不会增加资源的引用计数。当我们需要通过weak_ptr访问所指向的对象时,不能直接解引用,必须先将weak_ptr升级为shared_ptr,而lock方法就是实现这一升级的核心接口。

weak_ptr lock方法的基本用法
weak_ptr的lock方法会返回一个shared_ptr对象,这个返回的shared_ptr会和原有的shared_ptr共享资源的所有权,同时增加资源的引用计数。如果weak_ptr指向的资源已经被释放,lock方法会返回一个空的shared_ptr。
下面是lock方法的基础使用示例:
#include <iostream>
#include <memory>
int main() {
// 创建一个shared_ptr管理int资源
std::shared_ptr<int> sp = std::make_shared<int>(10);
// 用shared_ptr初始化weak_ptr
std::weak_ptr<int> wp(sp);
// 调用lock方法升级为shared_ptr
std::shared_ptr<int> sp2 = wp.lock();
if (sp2) {
// 升级成功,可以访问资源
std::cout << "升级成功,资源值为:" << *sp2 << std::endl;
} else {
std::cout << "升级失败,资源已被释放" << std::endl;
}
return 0;
}
弱引用升级为shared_ptr的完整流程
将weak_ptr升级为shared_ptr的整个流程可以分为三步:
- 第一步:确保weak_ptr已经通过shared_ptr初始化,或者已经被赋值为一个有效的weak_ptr对象,避免weak_ptr本身是空指针。
- 第二步:调用weak_ptr的lock方法,获取返回的shared_ptr对象。
- 第三步:判断返回的shared_ptr是否为空,如果不为空则升级成功,可以正常使用;如果为空则说明原资源已经被释放,不能使用该指针访问资源。
资源释放后的升级情况演示
当weak_ptr指向的shared_ptr管理的资源被释放后,再调用lock方法会得到空shared_ptr,示例如下:
#include <iostream>
#include <memory>
int main() {
std::weak_ptr<int> wp;
{
// 进入作用域,创建shared_ptr
std::shared_ptr<int> sp = std::make_shared<int>(20);
wp = sp;
// 此时sp的引用计数为1,wp指向该资源
auto sp2 = wp.lock();
std::cout << "作用域内升级结果:" << (sp2 ? "成功" : "失败") << std::endl;
} // 作用域结束,sp被释放,资源引用计数降为0,资源被销毁
// 再次尝试升级
auto sp3 = wp.lock();
std::cout << "作用域外升级结果:" << (sp3 ? "成功" : "失败") << std::endl;
return 0;
}
使用lock方法的注意事项
在实际使用weak_ptr的lock方法时,需要注意以下几点:
- 不要直接使用weak_ptr解引用访问资源,必须先通过lock升级为shared_ptr,否则会引发未定义行为。
- 每次需要访问资源时,都应该重新调用lock方法获取shared_ptr,不要在获取到一次shared_ptr后就长期保存使用,因为资源可能在这期间被其他shared_ptr释放。
- lock方法返回的shared_ptr的生命周期结束时会减少资源引用计数,不会影响weak_ptr本身的状态,weak_ptr的引用计数和shared_ptr的引用计数是分开管理的。
lock方法与expired方法的区别
有些开发者会用weak_ptr的expired方法先判断资源是否存在,再调用lock方法升级,这种方式其实存在线程安全隐患。expired方法只是判断资源是否已经被释放,但是在expired返回false之后,lock调用之前,资源可能刚好被其他线程释放,导致lock返回空shared_ptr。
而lock方法本身是原子操作,它会直接尝试升级,返回的结果是最新的状态,因此更推荐使用lock方法后判断返回的shared_ptr是否为空,而不是先调用expired再调用lock。下面是两种方式的对比示例:
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> sp = std::make_shared<int>(30);
std::weak_ptr<int> wp(sp);
// 不推荐的方式:先判断expired再lock
if (!wp.expired()) {
// 这里可能存在资源被释放的风险
auto sp1 = wp.lock();
// sp1可能为空
}
// 推荐的方式:直接lock后判断
auto sp2 = wp.lock();
if (sp2) {
// 升级成功,安全访问
std::cout << "资源值:" << *sp2 << std::endl;
}
return 0;
}
适用场景说明
weak_ptr配合lock方法升级为shared_ptr的场景通常用于解决shared_ptr的循环引用问题,比如两个对象互相持有对方的shared_ptr时,会导致资源无法释放,此时可以把其中一个持有改为weak_ptr,需要访问对方时再通过lock升级,既避免了循环引用,又能在资源存在时正常访问。
weak_ptrshared_ptrlock方法智能指针修改时间:2026-06-10 02:39:32