異常(exception)是c++語言引入的錯誤處理機制。它 採用了統一的方式對程式的執行時錯誤進行處理,具有標準化、安全和高效的特點。c++為了實現異常處理,引入了三個關鍵字:try、throw、catch。異常由throw丟擲,格式為throw[expression],由catch捕捉。try語句塊是可能丟擲異常的語句塊,它通常和乙個或多個catch語句塊連續出現。
try語句塊和catch語句塊必須相互配合,以下三種情況都會導致編譯錯誤:
(1)只有try語句塊而沒有catch語句塊,或者只有catch語句塊而沒有try語句塊;
(2)在try語句塊和catch語句塊之間夾雜有其他語句;
(3)當try語句塊後跟有多個catch語句塊時,catch語句塊之間夾雜有其他語句;
(4)同一種資料型別的傳值catch分支與傳引用catch分支不能同時出現。
在丟擲和接收異常的過程中,我們還要注意以下幾點。
1.被丟擲的異常物件什麼時候被銷毀?
用throw語句丟擲乙個物件時,會構造乙個新的物件,這個物件就是異常物件。該物件的生命週期從被丟擲開始計算,一直到被某個catch語句捕捉,就會在該catch語句塊執行完畢後被銷毀。考察如下程式。
#include
using namespace std;
class exclass
{ int num;
public:
exclass(int i)
{ cout<
程式輸出結果是:
constructing exception object with num=99
copy constructing exception object with num=100
copy constructing exception object with num=101
the number is 101
destructing exception object with num=101
destructing exception object with num=100
after catch
destructing exception object with num=99
用throw語句丟擲乙個物件時,會構造乙個新的物件,這個物件就是異常物件。該物件的生命週期從被丟擲時開始計算,一直到被某個catch語句捕獲,就會在該catch語句塊執行完畢後被銷毀。在上面的程式中,異常物件的num值為100,「destructing exception object with num=100」這句話在「aft程式設計客棧er catch」之前輸出,正好說明異常物件的銷毀時間是在它**獲的catch塊執行之後。
所以的catch分支在執行時類似一次函式呼叫,catch 的引數相當於函式的形參,而被丟擲的異常物件相當於函式呼叫時的實參。當形參與實參成功www.cppcns.com匹配時,就說明異常被某個catch分支所捕獲。catch後面的引數只能採用傳值、傳引用和傳指標三種方式,如果採用傳值方式,則會生成實參的乙個副本,如果實參是乙個物件,就會導致建構函式被呼叫。在上面的程式中,執程式設計客棧行catch(exclass e) 語句就是利用異常物件構造乙個物件e,因此會呼叫拷貝建構函式。
要注意的是:同一種資料型別的傳值catch分支和傳引用catch分支不能同時出現。
2.異常如果在當前函式沒有**獲會發生什麼?
在某些情況下,可能所有的catch分支都無法捕獲到丟擲的異常,這將導致當前函式執行的結束,並返回到主調函式中。在主調函式中,將繼續以上的捕捉異常的過程,直到異常**捉或最終結束整個程式。考察如下程式。
#include
using namespace std;
class exclass
{ int num;
public:
exclass(int i)
{ cout
程式的輸出結果:
constructing exception object with num=199
copy constructing exception object with num=200
the number is 200
destructing exception object with num=200
destructing exception object with num=199
continue to execute
從程式的結果可以看出:
(1)被丟擲的異常物件的num值為199,由於它沒有在函式throwexfunc()中**捉,所以它導致了throwexfunc()的執行結束(否則會輸出:exit throwexfunc())。在main()函式中,catch(exclass e)捕獲了異常物件,通過複製建構函式產生物件e,e的num值為200,catch語句塊執行完結束後,物件e首先被銷毀,緊接著銷毀異常物件。在這之後,程式繼續執行,輸出:continue to execute。
(2)catch(…)的意思是可以捕獲所有型別的異常。不提倡隨意地使用catch(…),因為這會導致異常型別的不精確處理,並降低程式的執行效率。但是,在程式的開發階段,catch(…)還是有用的,因為如果在精心安排異常捕獲之後,還是進入了catch(…)語句塊,說明前面的**存在缺陷,需要進一步改正。
(3)在捕捉異常物件時,還可以採用傳引用的方式,例如把catch語句寫成catch(exclass& e),這樣就可以不必產生異常物件的副本,減少程式的執行開銷,提高執行效率。
(4)在丟擲異常時,還可以丟擲乙個指標。當然這種做法並不總是安全的。程式設計客棧如果要確保安全,應該將指標指向全域性(靜態)物件的指標或指向動態申請的空間,或者被丟擲的指標在本函式內**獲。否則,利用乙個被丟擲的指向已經被銷毀的物件指標很危險。如果實在要用,首先,必須保證物件的析構函式不能對物件的內容作損傷性的修改,其次,物件的空間沒有被其他新產生的變數覆蓋。也就說,儘管物件被釋放,但它的有效內容依然保留在棧中。
c 異常丟擲和接收機制
c 語言中定義了一套關於異常的丟擲throw 和接收catch機制 1 其中丟擲的異常型別可以是乙個類物件,某一型別的資料等,如,丟擲某一型別的資料 int x throw x 等 丟擲某一類的物件 throw exception 2 丟擲異常的位置,可以在try中寫,如 trycatch exce...
C 中的異常丟擲和捕獲
在 c 語言中,如果發生錯誤,上級函式要進行出錯處理,層層上傳,容易造成過多的出錯處理 並且傳遞的效率比較低下。try catch exceptiontype var include using namespace std void func1 catch double cout catch fun...
C 異常丟擲機制
乙個程序中可以同時包含多個執行緒。我們通常認為執行緒是作業系統 可識別的最小併發執行和排程單位 不要跟俺說還有 green thread 或者 fiber,os kernel 不認識也不參與這些物件的排程 同一程序中的多個執行緒共享 段 和常量 資料 段 靜態和全域性變數 和擴充套件段 堆儲存 但是...