簡體   English   中英

使用std :: enable_shared_from_this時析構函數崩潰

[英]Crash in destructor when using std::enable_shared_from_this

我正在嘗試編寫一個類似類的升壓信號(作為學習c ++的實踐)。 我發現當我使用enable_shared_from_this ,我總是在析構函數中崩潰。 這是代碼(我正在使用vs2012更新2):

對此有何評論? 這個問題應該是shared_from_this()引起的,因為當我取消對signal_connection::disconnect的行( auto this_ = shared_from_this(); )的signal_connection::disconnect ,一切正常。

我知道在調用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_壽命足以解決該問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM