2014-01-28 37 views
2

我有一個目前看起來是這樣的(僞僞代碼)類:檢查異步方法在析構函數完成

class AsyncStore { 
public: 
    AsyncStore(); 
    ~AsyncStore() { 
    // Make sure writes have flushed somehow 
    } 

    void write_something() { 
    // Issue an asynchronous write, and return immediately 
    } 

    void sync_writes() { 
    // Check all writes could be flushed, and throw if any failed 
    } 
}; 

這有析構函數沒有辦法發出錯誤信號的(問題我們不能拋出,並且我們不能以任何其他方式表示錯誤)。

理想情況下,此類的用戶在調用析構函數之前會調用sync_writes(),並處理所有拋出的異常,這樣在銷燬時就沒有任何事情可做。

就目前而言,無法執行此操作。感覺這肯定是一個相對常見的問題 - 有沒有辦法處理這個問題,我可以保證在銷燬時沒有掛起寫入操作?

+0

「我們不能以任何其他方式表示有錯誤」。誰說的? –

+1

你會如何在析構函數中指示錯誤?您不能拋出或返回錯誤狀態。 –

+0

有很多方法可以發出錯誤信號。您可以將消息記錄到文件中,或者將值推送到日誌容器以便稍後處理。這取決於誰應該接收你的信號。 –

回答

1

您可以強制API使用者在銷燬對象之前調用sync_writes。如果析構函數進入未完成工作,terminate()或執行其他一些緊急操作(例如只是不等待工作並記錄錯誤)。

我認爲這是一個API設計問題。只需確定調用者必須正確關閉對象並在運行時執行它。如果打電話者違反API合同,他們不能期望得到正確的結果。

還有一種替代方法:強制API使用者註冊一個在發生錯誤時調用的回調函數。回調可以在構造函數中被接受。

+0

感謝您的建議 - 我認爲前一種方法可能最終成爲最佳選擇。後者的問題是人們可能會將其綁定到一個類的成員函數,該類的生存期與AsyncStore的生存期綁定。 –

+0

在存在共享資產(如端口,文件或緩衝區)的情況下,另一種可能性是對資產使用「shared_ptr」。特別是看看['std :: enable_shared_from_this'](http://en.cppreference.com/w/cpp/memory/enable_shared_from_this),看看它是否適用於你的情況。 – Edward

+0

這是在轉移問題,而不是解決問題。所以你把RAII扔出窗外,強迫每個人明確地調用close方法。現在,如果因拋出異常而導致堆棧展開,需要關閉對象時會發生什麼情況? –