c++異常處理ZZ
異常,通常是指程式困難檢測到的,運行是不正常的情況,例如被0除,數組越界訪問等等。
異常處理的文法通常是
try
{
throw()
}
catch()
{
}
關鍵字try以及它後的大括弧中的內容我們稱其為try塊。簡單的說,它包含的是可能會出錯的地方(就是我們要檢測的地方)。當我們檢測到一個錯誤資訊的時候,關鍵字throw就把這個錯誤拋出來(強呀:)),拋出來怎麼辦呢?拋哪去呢?我們的catch關鍵字就給我們解決掉了這個問題。catch通常用來接收throw拋出來的異常。請注意了,throw拋出來的類型要與catch接受的類型要匹配。就像把一個數字5隻能附給一個int型的a一樣(當然 int型的b也可以...耳後生風,似乎有磚飛來。。。)
下來,讓我來學習一下異常處理的三種用法:
1:常見的異常處理
我們來看下下一段的代碼:
#i nclude <iostream>
#i nclude <string>
#i nclude <math.h>
using namespace std;
class triangle //定義一個三角形的類
{
public :
float a,b,c,d; //三角形三邊a,b,c,海倫公式常量d
float s; //三角形面積
public:
triangle()
{}
triangle(float a1,float b1,float c1)
{
a=a1;
b=b1;
c=c1;
}
void judgment()//判斷是否是三角形
{
string yorn;
if((a+b)<c ||(a+c)<b || (c+b)<a)//任意兩邊和小於第三邊,就不是三角形
{
yorn="不是三角形";
throw(yorn);
} /*如果任意兩邊和小於第三邊,我們就認為是一個異常(不是三角形,讓我算什麼呢??),用throw拋出。注意,我們定義了一個string形的變數 yorn(是或不是),並將其拋出。接受的時候也要用string類型來接收。下面就會看到~~*/
}
void dimension()//計算面積
{
d=(a+b+c)/2; //海倫公式
s=sqrt(d*(d-a)*(d-b)*(d-c));
}
};
void main()
{
triangle a(7,2,3);
try
{
a.judgment();
a.dimension();
cout<<"三角形a的面積為: "<<a.s<<endl;
}
catch (string &err) //接受了,接受了,請注意,我還是定義了一個 string形的來接受的。那麼我能不能定義一個int 或別的類型的呢?可以,完全可以,只是接受不到罷了:)...又有磚飛來。。。*/
{
cout<<err<<endl;
}
}
當然,c++也給提供了一個萬能的接收器,
你也可以寫成這樣
catch(...)
{
cout<<"錯了夥計,你知道什麼是三角形嗎?"<<endl;
}
這裡的catch(...)就是一個萬能的接收器(別問我為什麼,c++規定就是這樣寫的,就像你不要問我為什麼要寫這篇文章一樣,夜深了,我還在寫著...寫著...對不起,跑遠了,拉回來.)
萬能接收器也可以和我寫的這個catch放一起用,比如你又可以寫成:
try
{
a.judgment();
a.dimension();
cout<<"三角形a的面積為: "<<a.s<<endl;
}
catch (string &err)
{
cout<<err<<endl;
}
catch(...)
{
cout<<"錯了夥計,你知道什麼是三角形嗎?"<<endl;
}
萬能接收器要寫在最後面。所有catch的最後一個,要麼是你定義的catch () (沒有萬能的),要麼是萬能的catch(...)
如果你非要寫在別的地方,那麼。。重寫編譯器吧。
2:異常規範
當我看著在類中成員函數 void judgment()
{
string yorn;
if((a+b)<c ||(a+c)<b || (c+b)<a)
{
yorn="不是三角形";
throw(yorn);
}
}
時,我的心情澎湃,不能平靜。會寫拋出了,會寫了,我要寫兩個,刪一個留一個。。。等,兩個throw,是的我還可以寫200個throw,但是我要拋出什麼類型呢?目前看來我只想拋出string類型的東西,萬一我手快拋錯了怎麼辦(沒辦法,菜鳥呀,菜鳥總有出錯的時候!)。ok,查下資料,喝口小水,看看有沒有解決的辦法...(翻書中...)
工夫不負我有心人呀,翻出了異常規範這個文法。讓我看看是怎麼實現的
還是上訴的成員函數,改寫成
void judgment() throw(string)
{
string yorn;
if((a+b)<c ||(a+c)<b || (c+b)<a)
{
yorn="不是三角形";
throw(yorn);
}
}
這樣,就可以保證我只能拋出string類型的異常。
在函數的參數列表和函數體之間,throw()語句就是一個異常規範。
編譯器保證不能拋出在throw()中包含的類型之外的異常。
比如,我們只想在函數中拋出的異常為int,string類型
我們就可以這樣寫我們的函數
viod myfun(int a,string b) throw(int ,string)
{
//函數實現
......
throw(int類型)
throw(string類型)
throw(char類型)//想拋嗎,估計拋不出來的,呵呵~~~~
......
}
這樣,就保證我們在函數中只能拋出類型為int,和string的異常。
3:異常和繼承
看代碼先
#i nclude <iostream>
#i nclude <string>
#i nclude <math.h>
using namespace std;
class triangle :public exception//定義一個三角形的類
{
public :
float a,b,c,d;
float s;
public:
triangle()
{}
triangle(float a1,float b1,float c1)
{
a=a1;
b=b1;
c=c1;
}
void judgment() throw(exception)//判斷是否是三角形
{
if((a+b)<c ||(a+c)<b || (c+b)<a)//任意兩邊和小於第三邊,就不是三角形
{
throw exception("不是三角形,玩我呀大哥");
}
}
void dimension()//計算面積
{
d=(a+b+c)/2; //海倫公式
s=sqrt(d*(d-a)*(d-b)*(d-c));
}
};
void main()
{
triangle a(7,2,3);
try
{
a.judgment();
a.dimension();
cout<<"三角形a的面積為: "<<a.s<<endl;
}
catch(exception &e)
{
cout<<e.what()<<endl;
}
}
上訴代碼寫的就是異常的繼承,triangle繼承自exceprion類,exceprion是c++類庫的一個標準異常類,triangle類繼承了對異常的處理,比如語句throw exception("不是三角形,玩我呀大哥");,這裡拋出的是一個exception類型的異常,我們在接受的時候就要用catch (exception &e)來接受,並且使用了一個exption提供的一個what方法,來輸入異常描述。
我們也可以不用類庫中的exception類,自己來寫一個異常處理的類。
下面是我寫的一個功能很簡單的異常處理類,我把它做為一個基類,用triangle來繼承它
#i nclude <iostream>
#i nclude <string>
#i nclude <math.h>
using namespace std;
class exec
{
private:
string error;
public:
exec()
{}
exec(string err)
{
error=err;
}
string geterr()
{
return error;
}
};
class triangle :public exec//定義一個三角形的類
{
public :
float a,b,c,d;
float s;
public:
triangle()
{}
triangle(float a1,float b1,float c1)
{
a=a1;
b=b1;
c=c1;
}
void judgment() throw(exec)//判斷是否是三角形
{
if((a+b)<c ||(a+c)<b || (c+b)<a)//任意兩邊和小於第三邊,就不是三角形
{
throw (exec("不是三角形,你玩我呀大哥"));
}
}
void dimension()//計算面積
{
d=(a+b+c)/2; //海倫公式
s=sqrt(d*(d-a)*(d-b)*(d-c));
}
};
void main()
{
triangle a(7,2,3);
try
{
a.judgment();
a.dimension();
cout<<"三角形a的面積為: "<<a.s<<endl;
}
catch(exec &e)
{
cout<<e.geterr()<<endl;
}
}
exec類就可以說是一個異常處理的類(我是專為異常處理寫的),triangle 繼承自它。我運行了一下,效果和上面用exception的效果是一樣的。不過我寫的就,哎~不說也罷(寫成這樣還要帖出來,suo哥呀,可要幫我擋磚的)。
以上就是我的一點關於異常處理的一點小小的學習感觸,同志們,踩著我的肩膀上吧。磚頭,就拿去扔別人吧,上了N年的學,學了N年的電腦,自以為對c++還掠知一二,哎~上了suo哥的課才知道,自己對c++不是掠知一二,而是一無所知呀。同志們,公勉吧。
夜深了,睡覺了。。。
文章歡迎抨擊,修改,指出不足之處,本人會非常感激~~