Как только блокировка на std :: weak_ptr вернула nullptr, может ли она снова стать ненулевой? - PullRequest
0 голосов
/ 25 января 2019

Если вы берете блокировку на 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 голосов
/ 25 января 2019
#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, он может стать «реанимированным из мертвых».

Может быть, это не то, что вы имели в виду. Но это , что вы спросили.

0 голосов
/ 25 января 2019

есть ли условия, при которых он мог бы возвращать ненулевое значение, или он фактически мертв?

Ну, в этот момент он "почти" мертв.lock вызывает expired способом, эквивалентным этому:

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

Затем, глядя на условие истечения срока действия:

Эквивалентно use_count() == 0.Деструктор для управляемого объекта, возможно, еще не был вызван, но разрушение этого объекта неизбежно (или, возможно, уже произошло).

В любом случае, для этого конкретного weak_ptr нет никакой возможности бытьпереназначен на другое значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...