c++ - 使用 std::enable_shared_from_this 时析构函数崩溃

标签 c++ c++11 shared-ptr

我正在尝试编写类似类的升压信号(作为学习 C++ 的练习)。我发现当我使用 enable_shared_from_this 时,我总是在析构函数中崩溃。这是代码(我使用的是 vs2012 update 2):

对此有何评论?这个问题应该是由 shared_from_this() 引起的,因为当我取消注释 signal_connection::disconnect 中的 (auto this_ = shared_from_this();) 行时,一切正常。

我知道在调用 shared_from_this() 之前它必须至少有一个有效的 shared_ptr。我的代码应该满足这一点。

代码:

    #include <memory>
    #include <map>

    class slot_manager;

    class signal_connection: public std::enable_shared_from_this<signal_connection>
    {
    public:
        signal_connection(slot_manager* manager)
            :manager_(manager)
        {}
    public:
        void disconnect() ;
    private:
        slot_manager* manager_;
    };

    class slot_manager
    {
    public:
        typedef std::shared_ptr<signal_connection> connection_type;
        typedef std::map<connection_type, int> map_type;
        typedef map_type::value_type map_value_type;
    public:
        void connect(int slot)
        {
            std::shared_ptr<signal_connection> c(new signal_connection(this));
            slots_.insert(map_value_type(c, slot));
        }
        ~slot_manager()
        {
            auto iter = slots_.begin();
            map_type::iterator iter2 = slots_.end();
            while (iter != slots_.end())
            {
                iter2 = iter++;
                iter2->first->disconnect();
            }
        }
        void disconnect(std::shared_ptr<signal_connection> connection)
        {
            auto c = slots_.find(connection);
            if (c != slots_.end())
            {
                slots_.erase(c);
            }
        }
    protected:
        map_type slots_;
    };

    void signal_connection::disconnect() 
    {
        if (manager_ != nullptr)
        {
            //auto this_ = shared_from_this();
            manager_->disconnect(shared_from_this());
            manager_ = nullptr;
        }
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
        slot_manager x;
        x.connect(1);
    return 0;
    }

最佳答案

问题是,在您将其管理器设置为 nullptr 之前,signal_connection 在 disconnect() 中被销毁,然后导致访问冲突,即通过调用经理的断开连接。这是因为管理器持有连接的唯一 shared_ptr,而您 erase() 那个。该对象不会使自己保持事件状态。当然,除非您取消注释该行。 this_ 只存在足够长的时间来规避问题。

关于c++ - 使用 std::enable_shared_from_this 时析构函数崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17343686/

相关文章:

c++ - 使用 C++11 散列自己的字符串类型

c++ - "std::shared_from_this"不能被它的派生类继承吗?

c++ - 制作 shared_ptr 的拷贝时会发生什么?

c++ - 如何使用 DirectX 捕获分层窗口?

c++ - 类型在编译时已知的虚拟方法

c++ - 为什么 sys socket recv 函数不填充数据而是返回字节长度?

c++ - std::tr1::shared_ptr 是否互斥?

c++ - 将参数传递给编译器以设置定义的变量?

c++ - 井字游戏

c++ - 如何用不同数量的默认参数包装一个函数,使其只有一个参数?