第七章主要介紹了如何使用異常來使你的程式更安全。
2.2 throw
2.3 沿著函式呼叫鏈上傳
2.4 異常的處理流程
3.標準異常
4. 區域性資源管理
丟擲int
//例一 丟擲int
voidf1(
int num,
int max =50)
丟擲string,注意,catch解析這個錯誤的時候,使用const char*型別接受
//例二 丟擲string
voidf2(
int num,
int max =50)
丟擲class有兩種寫法,一種是不丟擲具體例項,一種是建立例項以後再丟擲例項
//例三 丟擲class的兩種寫法
class
error
void
what()
private
:int _num;
int _max;};
voidf3(
int num,
int max =50)
cout <<
"建立成功"
<< endl;
}voidf4(
int num,
int max =50)
cout <<
"建立成功"
<< endl;
}
2.1.1 捕獲屬於catch的異常
當try中丟擲異常的時候,下面的catch會進行一一匹配,找到丟擲的異常型別,然後執行相應的catch中的程式。
處理丟擲的int
//01 例程1
cout <<
"丟擲int"
<< endl;
trycatch
(int len)
cout << endl;
處理丟擲的string
//02 例程2
cout <<
"丟擲string"
<< endl;
trycatch
(const
char
* str)
cout << endl;
處理丟擲的error類
//03 例程3-1
cout <<
"丟擲class1"
<< endl;
trycatch
( error& err)
cout << endl;
//03 例程3-2
cout <<
"丟擲class2"
<< endl;
trycatch
(error & err)
cout << endl;
2.1.2 在父類中查詢異常種類
當然也會存在丟擲的異常不在catch中的情況,這個時候,catch會檢測,被丟擲的異常的父類是否能夠與自己匹配,如果能,就會執行相應的catch
我們定義相應的異常類和丟擲異常的函式
// 從父類中尋找異常型別
class
error1
:public error};
voidf5(
int num,
int max =50)
cout <<
"建立成功"
<< endl;
}
使用catch捕獲異常,不過函式丟擲的是error1,而catch中寫的是error,但是仍然能夠正確執行,就是因為catch發現沒有可以匹配的異常型別,但是發現error1的父類就行error,所以接受error異常型別的catch,就能夠接受error1異常型別,然後執行catch
//01 從父類尋找異常型別
cout <<
"從父類尋找異常型別"
<< endl;
trycatch
(error & err)
cout << endl;
2.1.3 捕獲全部異常
還有一種寫法,能夠捕獲所有的異常,就是catch(…)
try
catch(.
..)
舉例
cout <<
"注意事項一,catch不能有包含關係"
<< endl;
trycatch(.
..) cout << endl;
catch
(error & err)
2.1.4 注意
如果catch語句相互包含,程式會執行錯誤,因為不知道該使用哪個catch了,比如我們把catch(…)放到前面,這個時候,後面的catch語句無論如何也不能執行,就被遮蔽掉了,程式是無法執行的。
cout <<
"catch(...)全部抓住"
<< endl;
trycatch(.
..) cout << endl;
也不能在建構函式中丟擲異常,尤其是建構函式中使用new的時候。因為,建構函式如果丟擲異常,意味著物件沒有定義成功,但是記憶體以及被分配了,物件沒定義,意味著不會執行析構函式,所以會造成記憶體洩露.
如果當前層級的catch不能很好的處理異常,可以使用throw,將異常往上一級丟擲,讓上一級的catch函式進行處理。只寫乙個throw;即可,不需要重複再寫throw的內容。而且,只有在catch中,才可以使用throw繼續往上一層丟擲異常
如果這個函式丟擲異常的時候,這個位置沒有catch函式,異常會沿著呼叫他的函式繼續往上丟擲,一直到有一層有了try-catch語句。不過,如果異常丟擲到main層,還不能被處理,程式會被強制終止。
void
level1()
void
level2()
intmain()
catch
(int len)
cout << endl;
return0;
}
編譯器對try中丟擲異常的綜合的處理過程是
除了我們自己定義的異常以外,c++還有自己內建的異常類,這些異常被稱為標準異常。
比如bad_alloc會在new不能提供足夠記憶體大小的時候被丟擲,這種異常一般定義在標準函式庫中。
所有的標準庫異常都**於抽象類exception,exception類中有乙個叫做what的虛函式,返回值為const char*,用來記錄具體是哪個標準異常被丟擲。
我們自定義異常的時候,可以繼承exception類作為父類,這樣的話,catch中寫exception,即可以捕獲所有型別的異常,並且能夠找出他們的名字。如果想要繼承exception,注意兩點
這裡要提兩個技巧,乙個是如何把多種混雜型別的串變成字串,另外乙個是如何把string變成const char*型別
繼承標準異常庫定義自己的異常
class
exceptionerror
:public exception
const
char
*what()
private
:int _num;
int _max;};
void
throwexceptionerror
(int num,
int max=50)
cout <<
"建立成功"
<< endl;
}
使用自己定義的異常
cout <<
"繼承標準異常庫"
<< endl;
trycatch
(exception & exp)
cout << endl;
下面這個例子,不妨從異常的角度來看看**錯了
extern mutex m;
voidf(
)
看似這個函式很正常,但是一旦process函式丟擲了異常,後面的記憶體釋放函式就不能執行了,就會造成記憶體洩露,如何避免這個問題呢
可以用try-catch語句來避免記憶體洩露
extern mutex m;
voidf(
)catch(.
..)}
這樣雖然是可行的,但是這麼寫,未免太囉嗦了,其實還有其他的解決方案
我們可以把記憶體型別的變數定義在類的建構函式中,這樣即使中間的process函式丟擲了異常,也能夠通過析構函式釋放記憶體。因為析構函式保證,會在丟擲異常結束程式執行之間執行完畢,能夠保證不發生記憶體洩露
voidf(
)
python第七章 python教程(第七章)
字典和集合 字典是python中唯一,乙個對映型別 如何建立乙個字典,如下 dict dict 滲透 網路安全 怎麼理解字典呢?現實生活中的字典可以通過首字母進行查詢要查詢的漢子,python也可以這樣理解,通過 前的元素查詢到冒號後的元素。為什麼說字典是唯一乙個對映型別呢?看圖。對映型別區別與序列...
第七章 函式
1.ansi c 允許函式原型的使用,函式宣告提供給編譯器和之後的呼叫函式返回值型別,引數型別和數量的資訊,而k c用單獨的列表給出引數的型別,編譯器只記住函式的返回值型別,但不儲存函式的引數數量和型別 2.沒有return語句的函式,隱式的返回 3.函式的原型可以單獨放於乙個標頭檔案中,一定要具有...
第七章總結
7.2.2畫直線 畫直線使用cdc類的lineto 函式兩個過載版本 bool lineto int x,int y bool lineto point point 引數x y或point指定直線的終點位置,此函式從當前點到指定的終點之間畫一條直線,當前點包括在直線上,而終點不包括在直線上。如果畫線...