一旦对std :: weak_ptr的锁定返回了nullptr,它又可以再次变为非null吗?

时间:2019-01-25 13:28:33

标签: c++ c++11

如果您锁定std::weak_ptr

    class foo {};

    auto s = std::make_shared<foo>();

    std::weak_ptr<foo> w{ s };

    s = nullptr;

    s.reset(new foo());

    auto l = w.lock(); // try to get previous foo

    std::cout << "locked: " << (l != nullptr) << std::endl;

输出:

locked: 0

一旦锁返回nullptr,是否有条件可以返回非空值,或者它实际上是无效的?

我的测试程序建议,一旦最初分配的对象的引用计数为零,则否,weak_ptr将始终返回nullptr。

2 个答案:

答案 0 :(得分:8)

  

是否存在每种情况下它都可以返回非null的条件,或者它实际上是无效的?

好吧,到那时,它“几乎”死了。 lock以与此等效的方式调用expired

expired() ? shared_ptr<T>() : shared_ptr<T>(*this)

然后,查看到期条件:

  

相当于use_count() == 0。托管对象的析构函数可能尚未被调用,但是该对象的销毁迫在眉睫(或者可能已经发生)。

无论哪种方式,都无法将特定的weak_ptr重新分配给另一个值。

答案 1 :(得分:4)

#include <iostream>
#include <memory>

int
main()
{
    using namespace std;
    shared_ptr<int> p(new int{3});
    weak_ptr<int> w = p;
    p = nullptr;
    auto l = w.lock();
    if (l == nullptr)
        cout << "l = nullptr\n";
    else
        cout << "l = " << *l << '\n';
    p.reset(new int{4});
    w = p;
    l = w.lock();
    if (l == nullptr)
        cout << "l = nullptr\n";
    else
        cout << "l = " << *l << '\n';
}

便携式输出:

l = nullptr
l = 4

是的,如果weak_ptr是从非空的shared_ptr分配的,它可能会“从死地复活”。

也许这不是您的意思。但这您所要求的。