通過繼承和重載exeception類定義新的異常
exeception類有一個虛函數
virtual const char* what() const;
//c++11之后不再用了
virtual const char* what() const noexcept;
|
const 后面跟throw() 不是函數,這個東西叫異常規格說明,表示 what 函數可以拋出異常的類型,類型說明放到 () 里,這里面沒有類型,就是聲明這個函數不拋出異常,通常函數不寫后面的就表示函數可以拋出任何類型的異常。 |
異常規格說明:
1、異常規格說明的目的是為了讓函數使用者知道該函數可能拋出的異常有哪些。 可以在函數的聲明中列出這個函數可能拋擲的所有異常類型。例如:
void fun() throw(A,B,C,D);
2、若無異常接口聲明,則此函數可以拋擲任何類型的異常。
3、不拋擲任何類型異常的函數聲明如下:
void fun() throw();
//繼承exeception類實現自己的異常
#include<iostream>
#include<exception>
using namespace std;
class MyException:public exception
{
public:
const char* what()const throw()
//函數后面必須跟throw(),括號里面不能有任務參數,表示不拋出任務異常
//因為這個已經是一個異常處理信息了,不能再拋異常。
{
return "MyException";
}
};
int main()
{
try
{
throw MyException();
}
catch(MyException& e) //傳引用,防止調用拷貝構造函數
{
cout<<"this is MyException"<<endl;
cout<<e.what()<<endl;
}
}
|
![]() |
//自己實現異常
#include<iostream>
#include<string>
using namespace std;
class exA
{
public:
exA(string strA):_strA(strA){ cout<<"exA()"<<endl; }
~exA(){ cout<<"~exA()"<<endl; }
virtual const char* what()const throw()
{
return _strA.c_str();
}
private:
string _strA;
};
class exB : public exA
{
public:
exB(string strB):_strB(strB),exA("exA"){ cout<<"exB()"<<endl; }
~exB(){ cout<<"~exB()"<<endl; }
const char* what()const throw()
{
return _strB.c_str();
}
private:
string _strB;
};
void fun(int n) throw(int,exA,exB) //只能拋出int,exA,exB類型錯誤
{
if(1==n){throw 1;}
else if(2==n){throw exA("this is exA");}
else if(3==n){ throw exB("this is exB");}
else {throw 2.2;}
}
|
int main()
{
try
{
// fun(1);
// fun(2);
fun(3); //這里最終調動的是exA
//因為在拋出異常對象的時候又建立了一個exA對象
//要想執行異常exB,就要注釋掉catch(exA& b)
//不注釋掉最后結果就是程序最后面一個
// fun(4); //運行出現下列錯誤
//terminate called after throwing an instance of 'double'
//Aborted (core dumped)
}
catch(int a)
{
cout<<"throw int"<<endl;
}
// catch(exA& b)
// {
// cout<<b.what()<<endl;
// cout<<"throw exA"<<endl;
// }
catch(exB& c)
{
cout<<c.what()<<endl;
cout<<"throw exB"<<endl;
}
catch(...)
{
cout<<"oth exception"<<endl;
}
return 0;
}
|
//throw int
//exA()
//throw exA
//~exA()
//exA()
//this is exA
//throw exA
//~exA()
|
//exA()
//exB()
//this is exB
//throw exB
//~exB()
//~exA()
//exA()
//exB()
//this is exB
//throw exB
//~exB()
//~exA()
|
#include<iostream>
#include<exception>
using namespace std;
class myException:public exception
{
public:
myException(const char* str):_str(const_cast<char*>(str)) { }
virtual ~myException()throw() { cout<<"~myException()"<<endl; }
//析構函數不能拋出異常,不許加異常規格說明throw()
const char* what()
{
return _str;
}
private:
char* _str;
};
int func(int a ,int b)throw(myException) //函數可能拋出myException異常
{
if(0==b)
{
throw *(new myException("除數不能為0")); //兩種都可以
}
return a/b;
}
|
int main()
{
int a = 5,b = 0;
int res;
try
{
res = func(a,b);
}
catch(myException& e)
{
cout<<e.what()<<endl;
// delete &e;
// 已經釋放了,不用再釋放了
}
cout<<res<<endl;
return 0;
}
|