[英]Why must the lock() function be used with a std::weak_ptr to safely extract the std::shared_ptr?
Here's an example which shows two different ways of getting a shared_ptr from a weak_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);
}
When it is run, this is the output:运行时,这是 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)
Clearly it is not always safe to access a weak pointer simply by constructing a shared pointer from it.显然,仅通过从弱指针构造共享指针来访问弱指针并不总是安全的。
My questions are:我的问题是:
Of what use is std::bad_weak_ptr at all?
std::bad_weak_ptr 到底有什么用?
You just saw the use of it.你刚刚看到了它的用途。
lock
returns an empty shared_ptr
; lock
返回一个空的shared_ptr
; the constructor throws an exception.构造函数抛出异常。
Using the shared_ptr
constructor means "I am certain that this weak_ptr
is valid, and if it isn't, that is an exceptional error condition that must be handled immediately."使用
shared_ptr
构造函数意味着“我确定这个weak_ptr
是有效的,如果不是,那是一个必须立即处理的异常错误情况。” If you are uncertain of the status of the weak_ptr
and want to check it, use lock
.如果您不确定
weak_ptr
的状态并想检查它,请使用lock
。
std::shared_ptr<Y>::shared_ptr(const std::weak_ptr<Y>& r) (11)
that allows doing it.std::shared_ptr<Y>::shared_ptr(const std::weak_ptr<Y>& r) (11)
允许这样做。if (sp)
.if (sp)
。
Note that
r.lock()
may be used for the same purpose: the difference is that this constructor throws an exception if the argument is empty, whilestd::weak_ptr<T>::lock()
constructs an emptystd::shared_ptr
in that case.请注意,
r.lock()
可用于相同目的:不同之处在于,如果参数为空,此构造函数将引发异常,而std::weak_ptr<T>::lock()
构造一个空的std::shared_ptr
在这种情况下。
Because that's how that std::shared_ptr
constructor works.因为这就是
std::shared_ptr
构造函数的工作方式。 From [util.smartptr.shared.const] :从[util.smartptr.shared.const] :
template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
Constraints :Y*
is compatible withT*
.约束:
Y*
与T*
兼容。
Effects : Constructs ashared_ptr
object that shares ownership withr
and stores a copy of the pointer stored inr
.效果:构造一个
shared_ptr
object 与r
共享所有权,并存储存储在r
中的指针的副本。 If an exception is thrown, the constructor has no effect.如果抛出异常,则构造函数无效。
Postconditions :use_count() == r.use_count()
.后置条件:
use_count() == r.use_count()
。
Throws :bad_weak_ptr
whenr.expired()
.抛出:当
bad_weak_ptr
r.expired()
时出现 bad_weak_ptr。
Why?为什么? Because that's the the semantics that the standard authors decided to give it.
因为这是标准作者决定赋予它的语义。 If you attempt to construct a
std::shared_ptr
directly from a std::weak_ptr
then you are asserting that the weak_ptr
is valid.如果您尝试直接从
std::weak_ptr
构造std::shared_ptr
,那么您就是在断言weak_ptr
是有效的。 If you're not sure, use lock
.如果您不确定,请使用
lock
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.