作者tropical72 (藍影)
看板C_and_CPP
標題Re: [問題] try catch(...)的問題
時間Fri Oct 28 16:44:06 2011
※ 引述《QQ29 (我愛阿蓉)》之銘言:
: try
: {
: 1. throw; //跑到這行就掛了?
: 2. throw exception(); //會進到catch
: 3. int a, b = 0; a= 1/b; //catch不到....
: 4. int *ptr = 0; *ptr = 5566; //catch 不到
: }
: catch(...)
: {
: }
直接看範例比較快。
try {
unsigned a=1, b=0;
if(b==0) throw
"分母為 0" ;
if(b>a) throw
"相減溢位" ;
if(b==a) throw
"a 等於 b" ;
throw
" 正常執行 "; /* 通常這個沒人在寫 */
}
catch (
char* msg) {
cout << msg << endl;
}
簡單用法大致上就樣,所以你的 3. 4
: 3. int a, b = 0; a= 1/b; //catch不到....
: 4. int *ptr = 0; *ptr = 5566; //catch 不到
catch 不到,純粹是因為沒有做 throw 動作,那些異常的判斷還是必須要靠
throw 丟出去,而
throw 後面通常會加一個 「例外物件」 出去,只是這例子的
例外物件是 char* 而已,當然丟出去的例外物件可以是 int、可以是
vector <int> (可能沒人丟這個),甚至有時候會這麼做
try{
unsigned a=1, b=2;
if(b==0)
throw 0;
if(b>a)
throw "相減溢位";
}catch(
int error_no){
cout << "error no : " << error_no << endl;
}catch(
char* error_msg) {
cout << "error msg : " << error_msg << endl;
}
可以丟出 (throw) 不同資料型態 (類別的話需注意轉形問題) 之例外物件,
甚至可以只針對其中幾種物件出來處理,而其它的例外物件全都丟到 ...
裡面處理, 像是這樣
try{
unsigned a=1, b=2;
throw 1.0;
if(b==0) throw 0;
if(b>a) throw "相減溢位";
}catch(int error_no){
cout << "error no : " << error_no << endl;
}catch(char* error_msg) {
cout << "error msg : " << error_msg << endl;
}
catch(
...){
cout << "nonknow expect!!\n";
}
丟出去的例外物件為 double ,不是 int ,也不是 char*,最後由
catch(...) 全部接收,所以至少可知道一件事:
一般而言,throw 後面一定會加上一個 例外物件
上面這規則註明了「一般而言」,因為有種例外,叫「復拋 (Rethrow)」,
但復拋之 throw 不會是寫在 try 裡面,而是寫在 catch 裡面,
說明請詳參 C++ Primer 4e 17.1.4,所以你的第一個 throw 也是錯的。
其它的 throw 問題,如解構、有 catch 沒 throw 等,會發生什麼事,
這些在 Primer 裡面也有提到。
C++ Primer 異常處理那裡,大致上都寫許多了,可能堅澀些所以沒那麼好懂,
建議還是要硬著頭皮掃過二遍。另一本書例外處理我倒覺得寫得還蠻不錯的,
The C++ Programming Language , exception handling 那章,
整章沒提到函式庫裡已有的例外類別,都在探討觀念。
--
No matter how gifted you are,
alone, can not change the world.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.78.41
推 winest:這篇簡單易懂XD 不知道throw能一次丟好幾個參數嗎 10/28 21:18
推 QQ29:看來我用C#去想C++ 完全的錯誤了 C#好像內部就是丟exception 10/28 21:58
→ QQ29:物件 10/28 21:58
推 VictorTom:推:) 10/28 23:07
→ tropical72:@winest:有兩個做法,一個是包成struct/class,另一個就 10/28 23:34
→ tropical72:是文中說的復拋,這二種方法並不衝突,可以合用。 10/28 23:35
→ diabloevagto:rethrow可以好幾個在傳? 10/28 23:49
→ tropical72:嗯,第二個方法當我沒說過吧,rethrow確實有點不同。 10/28 23:53
推 winest:t大的rethrow是指catch後丟別種型態的參數嗎 謝謝 10/29 10:06
→ diabloevagto:catch中可能處理過,但是還不完全,可以直接用throw; 10/29 10:14
→ diabloevagto:不用加任何參數,這個方式是把catch收到的在丟出去一 10/29 10:14
→ diabloevagto:次,這叫做rethrow,但在catch中也可以在丟別的出去 10/29 10:14
→ diabloevagto:不一定只能丟別的, 10/29 10:15
→ diabloevagto:不一定只能丟接收到的(上面推文錯了) 10/29 10:20
推 winest:試了一下大概知道意思了 謝謝XD 10/29 10:24
→ diabloevagto:c++ primer 這個部份真的寫得很棒喔!可以參考 10/29 10:26