[英]Why must the lock() function be used with a std::weak_ptr to safely extract the std::shared_ptr?
这是一个示例,它显示了从 weak_ptr 获取 shared_ptr 的两种不同方法:
#include <memory>
#include <iostream>
void print_shared1(std::weak_ptr <int> wp)
{
// always gets pointer safely
std::shared_ptr <int> sp(wp.lock());
std::cout << "wp = " << (sp ? *sp : 0) << std::endl;
}
void print_shared2(std::weak_ptr <int> wp)
{
// can crash if pointer has been freed
std::shared_ptr <int> sp(wp);
std::cout << "wp = " << (sp ? *sp : 0) << std::endl;
}
int main(int argc, char* argv[])
{
std::shared_ptr <int> s = std::make_shared<int>(1);
std::weak_ptr <int> w = s;
print_shared1(w);
print_shared2(w);
s.reset();
print_shared1(w);
print_shared2(w);
}
运行时,这是 output:
wp = 1
wp = 1
wp = 0
terminate called after throwing an instance of 'std::bad_weak_ptr'
what(): bad_weak_ptr
Aborted (core dumped)
显然,仅通过从弱指针构造共享指针来访问弱指针并不总是安全的。
我的问题是:
std::bad_weak_ptr 到底有什么用?
你刚刚看到了它的用途。 lock
返回一个空的shared_ptr
; 构造函数抛出异常。
使用shared_ptr
构造函数意味着“我确定这个weak_ptr
是有效的,如果不是,那是一个必须立即处理的异常错误情况。” 如果您不确定weak_ptr
的状态并想检查它,请使用lock
。
std::shared_ptr<Y>::shared_ptr(const std::weak_ptr<Y>& r) (11)
允许这样做。if (sp)
。
请注意,
r.lock()
可用于相同目的:不同之处在于,如果参数为空,此构造函数将引发异常,而std::weak_ptr<T>::lock()
构造一个空的std::shared_ptr
在这种情况下。
因为这就是std::shared_ptr
构造函数的工作方式。 从[util.smartptr.shared.const] :
template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
约束:Y*
与T*
兼容。
效果:构造一个shared_ptr
object 与r
共享所有权,并存储存储在r
中的指针的副本。 如果抛出异常,则构造函数无效。
后置条件:use_count() == r.use_count()
。
抛出:当bad_weak_ptr
r.expired()
时出现 bad_weak_ptr。
为什么? 因为这是标准作者决定赋予它的语义。 如果您尝试直接从std::weak_ptr
构造std::shared_ptr
,那么您就是在断言weak_ptr
是有效的。 如果您不确定,请使用lock
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.