深入分析異常機制

2021-04-13 04:40:03 字數 2374 閱讀 6918

我們知道c++和c最大的不同就是它更好的支援物件導向程式設計,封裝,多型,繼承,異常,命名空間.通用型程式設計等等.

對於面向機制為什麼說是更好的支援哪.是因為用c同樣可以編寫物件導向程式設計.我們都知道c函式可以通過結構體和函式指標來設計一些低階的類.但c++提供的class則更好的維護了資料的隱藏.而不是想c那樣任何資料都要通過函式來操作.c++是通過資料和方法的封裝來實現對資料的操作.

至於命名空間更多的是突出模組化.把一些你所認為有理由放在一起的資料 類 函式 等等放在同乙個命名空間中,來體現模組的概念,並且也減少了名字衝突.

下面我們來說說異常.異常的存在不一定總是一件很好的事,它的存在影響著程式在空間和時間上的優勢.很多編譯器也就因此可以設定成不支援異常的編譯機制.但你要保證你的每個編譯單位都沒有用到異常,在連線時才能順利連線.

而異常的存在一定是有原因的.從類庫的設計到使用者使用類庫程式設計無不涉及到異常.異常是類庫給使用者自己當家做主的好方法.

只要你用try塊去檢查,catch字句是不會另你失望的.

我們拿最熟悉的operator new來說 ,如果分配記憶體失敗就會丟擲乙個異常,bad_alloc  如果你要為這件事負責就一定要有這樣的** catchi(bad_alloc &)

在這裡說一下  new handler 大概是這樣的定義的  typedef   void (*new hander ) ()

也就是說new_handler是乙個指向引數和返回值都為void 的函式指標.

所以當你  set_new_handler(指向函式的指標) ; 時 ,當operator new失敗的話會先呼叫該函式.

而set_new_handler()的原型應該大概是這樣 new hander   set_new_hander (new  handler)

返回的是之前的函式指標.所以當你自己寫operator new時要注意這點,用完後要恢復. 當你為set_new_handler 傳遞乙個0時,就不呼叫任何函式 在operator new 失敗後.而直接丟擲bad_alloc異常.

接著從異常的傳遞來說一下,不論通過什麼方式來捕捉異常,異常丟擲的時候總會發生拷貝.

比如當我們有乙個自己寫的異常類 error

當我們在try 中throw 乙個該類的異常  ,在catch時不論是catch(error)值傳遞 還是catch(error &) 異常丟擲時都會拷貝乙個副本.值傳遞的話會用這個副本拷貝到catch(error)也就是說發生了兩次拷貝 如果是引用方式捕捉.則會直接用這個副本來初試化.我們知道含有隱式型別轉換的類做引數時,只能在接受值物件或者const 引用物件的函式時發生轉換.為什麼不能為非const引用物件發生乙個隱式轉換大家應該很清楚,原因就是為轉換產生的是臨時物件.而在異常中非const 引用同樣可以將丟擲異常產生的這個臨時副本捕獲..雖然通過指標捕獲沒有發生指向物件的複製.但會引起型別的吻亂.

對於異常捕獲時能夠發生的型別轉換只有2個  1 是 針對基類的catch可以處理派生類異常  所以一定要把派生類的catch寫在基類catch的上方.因為它只按順序來找   2是 所有指標都會轉換為void *

因為值方式捕捉會產生2個副本 所以大家最好用引用方式捕捉異常.

順便說一下.在catch中 如果throw; 則是直接丟擲捕捉時的那個副本.而 throw 物件; 則又會發生拷貝給呼叫者捕獲.

下面來說一下異常說明

就是在乙個函式宣告後邊加上類似的** throw () 如果不加則是說該函式允許丟擲任何異常.如果throw()沒有任何引數則是說不允許丟擲任何異常.如果乙個帶有throw()的函式呼叫了乙個throw(typename)的函式,並且異常真的發生了,則會呼叫unexpected函式.預設的行為就是終止程式.

所以要避免呼叫者的異常說明範圍小於被呼叫函式的異常說明.

函式指標也一樣

在more effective c++中說到摸板和異常說明不要同時使用,希望大家能看一下.

最後乙個避免的辦法就是保證為知型別的異常都會**獲

如果發生了乙個異常說明中沒有的異常則會呼叫unexpected函式.我們可以通過set_unexpected()

原型是這樣大概 unexpexted_handlerset_unexpected(unexpected_handler)

typedef void (*unexpected_handler)(); 和new_handler一樣是個函式指標.

在函式中如果有類似**throw;就會丟擲乙個型別為bad_exception的異常.你當然也可以自己決定丟擲的型別,這樣就明確的知道哪個型別是發生了異常說明中沒有的異常.在catch中對它進行捕獲,就會避免預設的unexpected函式的行為 即終止程式!

深入分析Java中CAS機制

在jdk 1.5中增加的乙個最主要的支援是atomic類,比如說atomicinteger,atomiclong,這些類可幫助最大限度地減少在多執行緒中對於一些基本操作 例如,增加或減少多個執行緒之間共享的值 的複雜性。而這些類的實現都依賴於cas compare and swap 的演算法。但是,...

IsPostBack深入分析

1 ispostback 介紹 ispostback是 page類有乙個 bool型別的屬性,用來判斷針對當前 form的請求是第一次還是非第一次請求。當 ispostback true時表示非第一次請求,我們稱為 postback,當 ispostback false時表示第一次請求。在 asp....

深入分析ConcurrentHashMap

再多執行緒的情況下,如果使用hashmap,就會導致死迴圈,導致cpu利用率接近100 所以如果是併發的情況不要使用hashmap 導致死迴圈主要是這段 當在多執行緒的情況由於沒有同步導致,著段 在擴容的時候會執行 do while e null 執行緒安全的hashtable 容器 hashtab...