try試圖執(zhí)行 try{}中的內(nèi)容
在可能出現(xiàn)異常的地方 拋出異常 throw
try下面 catch捕獲異常
catch(捕獲類型)...代表 所有其他類型
如果不想處理異常窗悯,繼續(xù)向上拋出 throw
-
如果沒(méi)有任何處理異常的地方,那么成員調(diào)用terminate函數(shù),使程序中斷
例:
int myDevide(int a, int b)
{
if (b == 0)
{
//拋出int類型異常
throw - 1;
}
return a / b;
};
void test()
{
int a = 10;
int b = 0;
try
{
myDevide(a, b);
}
//處理int類型異常
catch (int)
{
//throw; 再拋
cout << "int類型異常捕獲" << endl;
}
}
自定義異常進(jìn)行捕獲
class myException
{
public:
void printError()
{
cout << "自定義的異常" << endl;
}
};
int myDevide(int a, int b)
{
if (b == 0)
{
//拋出int類型異常
throw myException();
}
return a / b;
};
void test()
{
int a = 10;
int b = 0;
try
{
myDevide(a, b);
}
catch (int)
{
cout << "int類型異常捕獲" << endl;
}
catch (myException e)
{
e.printError();
}
}
棧解旋
從try開(kāi)始 到throw拋出異常之前 所有棧上的對(duì)象都會(huì)被釋放胆数,這個(gè)過(guò)程稱為棧解旋
棧上對(duì)象構(gòu)造函數(shù)順序和析構(gòu)函數(shù)順序相反
異常接口聲明
- 為了加強(qiáng)程序的可讀性粪般,可以在函數(shù)聲明中列出可能拋出異常的所有類型尝哆。例如:void func()throw(a,b,c);這個(gè)函數(shù)func能夠且只能拋出類型a,b,c及其子類型的異常
- 如果在函數(shù)聲明中包含異常接口聲明频蛔,則函數(shù)可以拋任何類型的異常仰禀,例如:void func()
- 一個(gè)不拋任何類型異常的函數(shù)可聲明為:void func()throw()
- 如果一個(gè)函數(shù)拋出了它的異常接口聲明所不允許拋出的異常照雁,unexcepted函數(shù)會(huì)被調(diào)用,該函數(shù)默認(rèn)行為調(diào)用terminate函數(shù)中斷程序
異常的生命周期
默認(rèn)構(gòu)造-->拷貝構(gòu)造--->調(diào)異常方法--->析構(gòu)拷貝出的異常類--->析構(gòu)默認(rèn)構(gòu)造類
如果 myException e答恶,會(huì)多開(kāi)銷一個(gè)數(shù)據(jù)饺蚊,調(diào)用拷貝構(gòu)造
如果myException *e,不new 提前釋放對(duì)象,new自己管理delete
推薦myException &e,容易些悬嗓,而且就一份數(shù)據(jù)
class myException
{
public:
void printError()
{
cout << "自定義的異常" << endl;
}
};
int myDevide(int a, int b)
{
if (b == 0)
{
//拋出int類型異常
throw myException();
}
return a / b;
};
void test()
{
int a = 10;
int b = 0;
try
{
myDevide(a, b);
}
catch (int)
{
cout << "int類型異常捕獲" << endl;
}
//這里會(huì)調(diào)用拷貝構(gòu)造污呼,會(huì)多異常開(kāi)銷
catch (myException e)
{
e.printError();
}
/*
這樣不會(huì)調(diào)用拷貝構(gòu)造
catch (myException &e)
{
e.printError();
}
*/
}
異常的多態(tài)使用
class BaseException
{
public:
virtual void printError()
{
}
};
class NullPointerException:public BaseException
{
public:
virtual void printError()
{
cout<<"空指針異常"<<endl;
}
};
class OutofRangeException:public BaseException
{
public:
virtual void printError()
{
cout<<"越界異常"<<endl;
}
};
void doWork()
{
throw NullPointerException();
}
void test()
{
try{
doWork();
}
catch(BaseException & e)
{
e.printError();
}
}
使用系統(tǒng)標(biāo)準(zhǔn)異常類
#include <stdexcept>
throw out_of_range("aaa")...
catch(out_of_range &e) {cout<<e.what()<<endl;};
編寫(xiě)自己的異常類
- 自己的異常類 需要繼承于 exception
- 重寫(xiě) 虛析構(gòu) what()
- 內(nèi)部維護(hù)以下錯(cuò)誤信息 字符串
- 析構(gòu)時(shí)候傳入 錯(cuò)誤信息字符串,what返回這個(gè)字符串
- string轉(zhuǎn)char* 用c_str()
class MyOutofRangeException :public exception
{
public:
MyOutofRangeException(string errorInfo)
{
ErrorInfo = errorInfo;
}
virtual ~MyOutofRangeException()
{
}
virtual const char* what()const
{
return ErrorInfo.c_str();
}
private:
string ErrorInfo;
};
class Person
{
public:
Person(string name, int age)
{
name = name;
if (age < 0 || age>200)
{
throw MyOutofRangeException(string("年齡越界!"));
}
age = age;
}
string name;
int age;
};
void test()
{
try {
Person p("大魔王", 1000);
}
catch (MyOutofRangeException& e)
{
cout<<e.what()<<endl;
}
}