2011-04-21 96 views
0

直覺告訴我拋出的類型越簡單越好。最好拋出一個int而不是一個指針,最好拋出一個結構而不是一個類。在這種情況下,儘管有必要使用動態分配的成員來拋出幾乎完整的類。在堆中分配內存很方便,因爲緩衝區可能會變得很長,並且複製會很昂貴;它不需要方法,因爲它可以作爲其他對象的控制/參數結構,但是它可以方便地將它構建在堆中,以便向struct拋出指針並具有析構函數來清理內存。越簡單越好,那麼析構者應該是虛擬的嗎? 省略虛擬表vtables不會影響異常通過結構基類拋出異常對象

從這個結構體中派生類作爲基類的好處是增加更多的數據,而不是多態方法。指針可能會從異常點前面幾層被捕獲,並在模塊之間傳遞,因此對象應該儘可能清潔,儘可能避免複合錯誤。

+2

你不應該拋出一個int或一個指針。在這種情況下更簡單。此外,儘量減少構造函數需要做的工作量,特別是涉及動態內存的任何事情。如果這些操作失敗,則無法拋出異常而無需終止程序。 – 2011-04-22 00:21:18

+4

結構並不比一個類更「簡單」(實際上它們不是獨立的實體:它們之間的差異只存在於指定成員訪問規則的方式以及定義類型時的繼承方式中)。聚合比一些真正複雜的類型更簡單,否則它可能會創建;你可能會想到這一點。那個結構只能是聚合是一個神話。 – 2011-04-22 00:36:44

+0

@ Dennis:如果構造異常類型時拋出異常,則不存在終止風險;只有在*拋出之後和處理之前拋出某些東西*。 – 2011-04-22 07:00:52

回答

1

看看std :: exception並從中繼承。

只有當您期望人們將該類用作基類時,析構函數才應該是虛擬的。

+0

注意'std :: exception'(及其親屬)的'what()'方法是虛擬的,所以關於具有vtables的異常的擔心顯然是沒有意義的。 – 2011-04-21 22:55:45

1

僅當通過指向基類的指針刪除對象時,才需要虛擬析構函數。在異常類型的情況下,您不應該動態創建它們,而應該根據值拋出。所以不需要通過基類指針或其他方法刪除它們,因此不需要虛擬析構函數。

話雖如此,與你提到的動態分配數據相比,v表的成本很小,並且與拋出異常的成本相比,你應該總是贊成效用而不是效率,除非有證明需要優化。我建議您從std::exception中派生所有異常類型,以便您可以統一處理代碼和標準庫(以及其他庫)引發的錯誤。這已經有一個虛函數(what(),返回一個消息字符串)和一個虛擬析構函數。