Привязка функции weak_ptr? Зная, когда истечет срок действия weak_ptr?

Мне нужна помощь и объяснение, пожалуйста, я немного смущен :(

У меня есть «слабый» менеджер, который удерживает weak_ptr для других объектов в моей программе. Я хотел бы знать, когда срок действия weak_ptr истекает в тот момент, когда он истекает (т.е. shared_ptr, на который он указывает, уничтожает элемент).

Я просмотрел некоторые сети о привязке weak_ptr, но я немного запутался во всем этом, поэтому любая помощь будет оценена по достоинству. Я наткнулся на этот ответ (https://stackoverflow.com/questions/11680680/binding-to -a-weak-ptr), но не совсем понимаю, так как мало что делал с std::bind. Как это работает с weak_ptr? Если я привяжу к нему функцию, будет ли эта функция вызываться каждый раз, когда что-то происходит с weak_ptr?

По сути у меня есть что-то вроде этого:

#include <iostream>
#include <list>
#include <memory>
#include <functional>
#include <algorithm>

struct Obj {};

class weakManager
{
public:
    unsigned int addItem(std::shared_ptr<Obj>& item)
    {
        items_.push_back(std::weak_ptr<Obj>(item));
        return items_.size() - 1;
    }

    void addObserver(std::function<void(unsigned int ID)> observer)
    {
        obsevers_.push_back(observer);
    }

    unsigned int getValidItems()
    {
        unsigned int validItems = 0;
        std::for_each(items_.begin(), items_.end(), [&validItems](std::weak_ptr<Obj>& item) 
            {
                if (!item.expired())
                    ++validItems;
            });
        return validItems;
    }

private:
    std::list<std::weak_ptr<Obj>> items_;
    std::list<std::function<void(unsigned int ID)>> obsevers_;
};


int main(int argc, const char * argv[]) 
{
    weakManager manager;

    manager.addObserver([](unsigned int ID) 
        {
            std::cout << "Observer says, item " << ID << " expired...\n";
        });

    {
        std::shared_ptr<Obj> someItem(new Obj);
        std::cout << "Item with ID : " << manager.addItem(someItem) << " added.\n";

        std::cout << "Manager has " << manager.getValidItems() << " valid item(s).\n";
    }
    std::cout << "Manager has " << manager.getValidItems() << " valid item(s).\n";

    return 0;
}

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

Любая помощь будет оценена. Большое спасибо.


person lfgtm    schedule 11.10.2019    source источник
comment
вам нужно будет добавить вызывающий наблюдатель для удаления в исходном shared_ptr из weak_ptr, чтобы иметь такое поведение   -  person bartop    schedule 11.10.2019
comment
Хорошо, спасибо, не совсем следую tbh. Вы говорите, что, возможно, мне следует держать shared_ptr в менеджере и проверять, когда счетчик ссылок shared_ptr достигает 1, то есть тот, что в менеджере, остается единственным? Вместо того, чтобы иметь weak_ptr в менеджере? Ваше здоровье.   -  person lfgtm    schedule 11.10.2019
comment
Нет, я говорю о том, что у вас должен быть пользовательский модуль удаления для shared_ptr, который вы хотите проверить. Средство удаления будет вызывать наблюдателей, когда объект удаляется (и weak_ptrs становятся недействительными).   -  person bartop    schedule 11.10.2019
comment
Нет, он говорит, что деструктор всего, чем вы управляете, должен сообщить менеджеру, что он уничтожает сам себя.   -  person Cubic    schedule 11.10.2019
comment
Хорошо спасибо. Ясно, значит, weak_ptr не может знать, когда срок их действия истекает? Означает ли это, что shared_ptr лучше использовать в менеджере, а weak_ptr использовать только для других целей. Дизайн системы в настоящее время не настроен таким образом, поскольку shared_ptr владельцы просто создают shared_ptr объекты и могут добавлять или не добавлять их в менеджер для потенциального использования другими. Означает ли это, что когда владелец создает ресурс, ему уже нужно знать, будет ли он использоваться слабым менеджером? проблема в том, что менеджер не знает, когда у него просроченный товар. :(   -  person lfgtm    schedule 11.10.2019
comment
невозможно, чтобы weak_ptr знал, когда истекает срок их действия? - weak_ptr знает, когда истекает их срок действия. Если вы попытаетесь lock() использовать weak_ptr с истекшим сроком действия, он вернет shared_ptr на нулевой указатель. Кроме того, weak_ptr имеет метод expired(), который вы можете вызывать напрямую (lock() проверяет expired() внутри).   -  person Remy Lebeau    schedule 11.10.2019
comment
@RemyLebeau спасибо, да, я знаком с тем, как использовать weak_ptr таким образом, однако для этого требуется, чтобы вызывающая сторона вызывала его извне, чтобы узнать, истек ли срок его действия, я бы хотел, чтобы weak_ptr вызывал какую-то функцию или чтобы иметь возможность уведомлять некоторые внешние модуль в момент истечения срока его действия, а не ждать, пока внешний модуль проверит, истек ли срок его действия.   -  person lfgtm    schedule 11.10.2019