2011-08-25 88 views
0

我有一個程序負責讀取數據,格式化它並創建記錄,並將記錄輸出到文件。本次討論的重要的類是:如何在錯誤情況下處理對象銷燬與非錯誤情況

  • RecordGenerator - 包含控制主流 (獲取數據,格式,輸出)
  • 文件管理線程 - 管理輸出文件。記錄發送到這個 類,然後將它放入收費文件中。
  • OUTPUTFILE - 包含記錄的文件的抽象,具有 打印(),close()方法,等等。這些對象由FileManager

擁有在正常關機過程中,析構函數,這些所有的類都被調用,這導致所有剩餘的記錄被刷新到當前的輸出文件,然後它被關閉。這確保我們不會丟失任何數據。 但是,在發生錯誤的情況下,我們需要關閉,但我們不想刷新並關閉文件,因爲數據可能已損壞。通常會發生什麼是一個異常將被拋出,在RecordGenerator中被捕獲,然後決定這是否是致命錯誤。如果是,它將啓動應用程序關閉。在這一點上FileManager被破壞,但需要知道是否有錯誤。同樣,當FileManager被破壞時,這會導致OutputFile被破壞,這也需要知道是否有錯誤。

我的第一反應是剛剛添加設置錯誤標誌這些類的一些公共功能,所以RecordGenerator可以調用FileManager::setErrorFlag()然後可以調用OutputFile::setErrorFlag()。添加這些鏈對我來說似乎是一種非常難聞的氣味,尤其是如果你認爲目標鏈可能比這更長。

有沒有更好的方法來處理這種情況?

回答

1

這是一個典型的問題,當人們開始使用RAII時,它不會被使用。破壞者應該清理資源並且恢復他們負責的任何東西。他們應該而不是提交更改。典型的異常安全的C++代碼如下所示:

  • 分配資源
  • 做點什麼
  • 提交更改

例如:

X& X::operator = (const X& x) 
{ 
    X y(x); // allocate 
    this->swap(y); // commit 
    return *this; 
} 

void f() 
{ 
    Transaction t(...); // begin transaction 
    // operate 
    t.commit(); // commit transaction 
} 

void g() 
{ 
    File f(...); // open file 
    // write to file 
    f.flush(); // flush the buffers, this may throw but not f.~File() 
}