地图中过期的weak_ptr会发生什么

时间:2016-03-21 13:56:00

标签: c++ shared-ptr weak-ptr

我想了解weak_ptr已过期的地图中的条目(类型为boost :: 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;
    }

Java中的WeakSet文档说,当weak_ptr到期时,该条目被删除。因此,想一想检查地图是否表现出类似(或未定义)的行为。

谢谢!

2 个答案:

答案 0 :(得分:6)

  

地图中的相应条目是否会自动删除?

不,它没有。该条目将继续存在。地图和shared_ptr是完全不相关的实体。最后shared_ptr所做的所有破坏都是免费记忆。

weak_ptr的优势在于weak_ptr将能够知道shared_ptr是否已被删除。这是expired()lock()成员函数的用途。但是,一旦它过期,您仍然可以将其从地图中删除。

答案 1 :(得分:3)

  

地图中的相应条目是否会自动删除?

绝对不是。要实现std::map::find(),必须修改映射,删除过期的元素,这是因为合同而无法完成的。特别是const版本。