简体   繁体   English

为什么 lock() function 必须与 std::weak_ptr 一起使用才能安全地提取 std::shared_ptr?

[英]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:我的问题是:

  1. In the function print_shared2, why are the semantics of wp.lock() not used during the construction of sp?在function print_shared2中,为什么在sp的构建过程中没有用到wp.lock()的语义?
  2. Of what use is std::bad_weak_ptr at all? std::bad_weak_ptr 到底有什么用?

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

  1. There is the constructor 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)允许这样做。
  2. While constructing a shared pointer it checks 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, while std::weak_ptr<T>::lock() constructs an empty std::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 with T* .约束Y*T*兼容。
Effects : Constructs a shared_ptr object that shares ownership with r and stores a copy of the pointer stored in r .效果:构造一个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 when r.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.

相关问题 std :: weak_ptr:lock或shared_ptr构造函数? - std::weak_ptr: lock or shared_ptr constructor? 使用std :: weak_ptr和std :: shared_ptr进行阴影 - Using std::weak_ptr with std::shared_ptr for shadowing std :: shared_ptr,std :: weak_ptr和控制块 - std::shared_ptr, std::weak_ptr and control block 使用 std::shared_ptr/weak_ptr 的简化观察者模式 - simplfied observer pattern with std::shared_ptr/weak_ptr std :: move_ptr :: lock的返回值弄乱了shared_ptr的引用计数? - std::move return value of weak_ptr::lock messing up reference count of shared_ptr? 使用shared_ptr和weak_ptr来管理std :: function safe的生命周期? - Is using shared_ptr and weak_ptr to manage lifetime of std::function safe? 将std :: shared_ptr的容器(std :: vector)过滤到std :: weak_ptr的容器 - Filtering a container ( std::vector ) of std::shared_ptr to a container of std::weak_ptr 对象std :: shared_ptr是否可以通过std :: weak_ptr找到? - Is object std::shared_ptr findable by its std::weak_ptr? std::weak_ptr 和相应的 std::shared_ptr 之间是否存在数据竞争? - Is there any data race between std::weak_ptr and corresponding std::shared_ptr? 没有可行的将std :: weak_ptr转换为std :: shared_ptr的方法调用 - No viable conversion std::weak_ptr to std::shared_ptr for method call
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM