2016-02-17 84 views
3

代碼安全嗎?std :: bind中的shared_from_this如何在對象不存在的情況下工作?

class C : public std::enable_shared_from_this<C> { 
    void start() { 
      boost::asio::async_write(socket_, boost::asio::buffer(message_), 
      std::bind(&tcp_connection::handle_write, shared_from_this(), 
      _1, _2)); 
    }; 
    // ... 
}; 

class D { 
    void start() 
    { 
     std::shared_ptr<C> cptr = std::make_shared<C>(); // (1) 
     cptr->start(); 
    } // (2) 
}; 

如果消息很長,則async_write操作可能需要很長時間。

只有一個shared_ptr指向C對象在點(1)。 start()被調用,start()完成並在(2)變量cptr超出範圍並被銷燬。

async_write已完成寫入操作,回調被調用;這會導致崩潰,因爲shared_from_this()會嘗試將shared_ptr設置爲不存在的對象。

這是對什麼發生的描述是正確的?

回答

6

不,你是不對的。

shared_from_this()呼叫前start回報情況。得到的shared_ptr的副本由bind的結果保存。

所以,當你到達(2)只有兩個引用的對象之一已經和

+0

非常感謝你仍然活着。我不想寫新的問題。我也想知道如果在上面的代碼中處理程序不會是一個方法(所以在綁定中沒有'shared_from_this'或'this') - 處理程序將是一個函數。在D :: start中,我創建了一個普通變量:'C c'。如果c在async_write完成之前被銷燬,可以嗎?在這種情況下,回叫總是被稱爲好嗎? – peter55555

+0

這取決於。如果處理程序以任何方式訪問'c'(例如通過一些指針或引用),那麼你就有問題了。如果不是,那很好。 (另一種選擇是將'c'的副本傳遞給處理程序;這是否有效取決於處理程序的細節。) –

相關問題