Что происходит с просроченным weak_ptr на карте

Я хотел бы понять, что происходит с записью (типа boost::weak_ptr) на карте, срок действия weak_ptr которой истек. Соответствующая запись на карте автоматически удаляется?

Ключ представляет собой целое число, а соответствующее значение — weak_ptr.

Пример кода, который я написал, но не смог его скомпилировать

    #include <iostream>
    #include <map>
    #include <boost/enable_shared_from_this.hpp>

    using namespace std;

    class Foo : public boost::enable_shared_from_this<Foo> {
    public:
        Foo(int n = 0) : bar(n) {
            std::cout << "Foo: constructor, bar = " << bar << '\n';
        }
        ~Foo() {
            std::cout << "Foo: destructor, bar = " << bar << '\n';
        }
        int getBar() const { return bar; }
        boost::shared_ptr<Foo> inc_ref() {
            return shared_from_this();
        }
    private:
            int bar;
    };

    std::map<int, boost::weak_ptr<Foo> > mappy;

    int main()
    {
        boost::shared_ptr<Foo> sptr(new Foo(1));

        std::pair<std::map<int, boost::weak_ptr<Foo> >::iterator, bool> res = 
mappy.insert(std::make_pair(10, sptr));

        if (!res.second ) {
            cout << "key already exists "
                             << " with value " << (res.first)->second << "\n";
        } else {
            cout << "created key" << "\n";
        }

        std::cout << "sptr use count  "<< sptr.use_count() << '\n';

        sptr.reset();

        std::cout << "sptr use count  "<< sptr.use_count() << '\n';

        std::map<int, boost::weak_ptr<Foo>, std::less<int> >::iterator map_itr = mappy.find(10);
        if (map_itr == mappy.end()) {
            cout << "Entry removed" << "\n";
        } else {
            cout << "Entry found: " << map_itr << "\n";
        }

        return 0;
    }

В документации WeakSet в Java говорится, что запись удаляется по истечении срока действия weak_ptr. Поэтому подумал о том, чтобы проверить, демонстрирует ли карта подобное (или неопределенное) поведение.

Спасибо!


person Maddy    schedule 21.03.2016    source источник


Ответы (2)


Соответствующая запись на карте автоматически удаляется?

Нет, это не так. Запись будет продолжать существовать. Карта и shared_ptr совершенно не связаны друг с другом. Все, что делает уничтожение последнего shared_ptr, это освобождает память.

Преимущество weak_ptr в том, что weak_ptr сможет узнать, был ли shared_ptr удален или нет. Вот что говорят expired() и lock() предназначены для. Однако по истечении срока его действия вы все равно можете удалить его с карты.

person Barry    schedule 21.03.2016
comment
Удаляет ли любой из контейнеров std просроченный weak_ptr автоматически как запись? - person Maddy; 21.03.2016
comment
@ Мэдди Нет. Вы можете реализовать этот механизм самостоятельно (написать собственный модуль удаления, который сохраняет ссылку на карту, которая ищет соответствующий weak_ptr и т. д.), но это звучит чрезвычайно тяжело и почти наверняка не то, что вы хотите делать в любом случае . - person Barry; 21.03.2016

Соответствующая запись на карте автоматически удаляется?

Точно нет. Для этого std::map::find() пришлось бы изменить карту, удалив элементы с истекшим сроком действия, чего он не может сделать из-за контракта. Особенно const версия.

person Slava    schedule 21.03.2016