2014-02-11 105 views
3

對於錯誤處理,異常是我的問題,因爲我的代碼將是一個動態鏈接庫。此外,我認爲例外只應在特殊情況下使用。但我會遇到可能會發生錯誤的情況,這並非例外。另一個問題是我的庫將從C#調用。因此,對所有錯誤使用異常在這裏似乎不是正確的選擇。錯誤堆棧與std :: error_code

但我發現std :: error_code和std :: error_category的概念很愉快,並希望在我的應用程序中使用它。不過,我也想提供某種錯誤的堆棧跟蹤。

考慮一個例子: 用戶想要從數據庫加載域對象。要加載這個域對象,應用程序需要加載不同表中的行。假設找不到其中一個必需的行。在這種情況下,數據庫層會生成一些「未找到」錯誤。如果我將這個錯誤全部傳播給用戶,錯誤消息將不會很有幫助,因爲沒有人知道找不到。同樣,如果每個圖層處理較低層的錯誤並生成一個相應的新錯誤,抽象出低級錯誤,那麼我最終會得到類似「無法從數據庫加載」這樣的事情,這又不是很有幫助。我想要的是擁有兩者。也就是說,每個圖層都會抽象出從任何較低級別獲得的錯誤,以便能夠向最終用戶顯示描述性消息,但同時我不想丟失有關低級別錯誤的信息。 所以我想有一個像錯誤堆棧跟蹤的東西。

我想過從std :: error_code派生出來的,並用一個指向基礎std :: error_code的指針和方法來獲得所有這些基礎對象。但是,我不確定這種技術是否會是一個好主意,因爲我在設計std :: error_code時注意到了這一點,從而使其效率更高。

我們希望error_code是一個值類型,可以在不分片的情況下進行復制,也不需要堆分配,但我們也希望它具有基於錯誤類別的多態行爲。

編輯 我覺得現在這種技術也將引入切片的問題,不是嗎?

編輯2 我現在想通過派生std :: error_code來實現它。而不是一個指針,什麼需要堆分配的地方,我的派生類將有一個boost ::可選。這樣,內部錯誤代碼就可以通過複製而在堆棧上創建。一個不存在的內部錯誤代碼可以用boost :: optional正確表示。切片仍然是一個問題,但我想這是可以忽略的,因爲將派生類的實例分配給std :: error_code變量不是必需的,即使發生這種情況,我也只會丟失有關內部錯誤代碼的信息。此外,我可以提供從std :: error_code到我的派生類沒有內部錯誤代碼的轉換。

編輯3 我沒想到的,這是不可能有包含一個boost ::可選的本身的類。所以現在我沒有看到任何我沒有在堆上分配的東西的可能性。

+0

你爲什麼不帶'inner_exception定義自己的'的std :: exception'派生異常類()'方法返回的內部異常(源自較低的水平)?你的用戶界面甚至可以捕獲一個'business_exception',但通過inner_exception()進行導航,你可以記錄每一層都發生的事情(好吧,**如果你想這樣做,可能存在安全原因,細節)。 –

+0

哦BTW IMO'std :: error_code'和'std :: error_category'對於你的場景來說是不正確的。應用程序_應該使用異常來通知錯誤,錯誤代碼是非C++環境的遺產(例如操作系統API或設備驅動程序)。在這種情況下,IMO應該創建一個封裝函數,用'std :: error_code'封裝錯誤代碼;使用C++ ish接口公開它們,然後使用異常來管理應用程序中的錯誤(使用error_code()成員自己的異常來獲取低級錯誤代碼(如果有的話)。 –

+0

我不能使用異常,因爲我正在編寫的代碼應該是一個動態鏈接庫 – sigy

回答

1

終於我來自std::error_code。我的派生類有一個成員,它是指向同一個類的實例的指針。我爲該類添加了wrap()方法,該類將同一類的實例作爲參數並在堆上分配它的副本。我的派生類的析構函數確保內存再次釋放。我爲這個內部錯誤代碼添加了一個getter方法。這樣我可以堆疊幾個錯誤代碼。缺點是,我需要堆分配,但我只是希望,在我的情況下,這不會導致重大的性能問題。 我的課程還提供從std::error_code轉換。


​​3210