1. catch語(yǔ)句塊中可以拋出異常
-
catch
中拋出的異常需要外層的try...catch...
捕獲
問(wèn)題: 為什么要在
catch
中重新拋出異常齿坷?
catch
中捕獲的異常可以被重新解釋后拋出翎苫,工程開(kāi)發(fā)中使用這樣的方式統(tǒng)一異常類(lèi)型逻卖。
編程說(shuō)明:異常的重新解釋示例1
#include <iostream>
#include <string>
using namespace std;
void Demo()
{
try
{
try
{
throw 'c';
}
catch(int i)
{
cout << "Inner: catch(int i)" << endl;
throw i;
}
catch(...)
{
cout << "Inner: catch(...)" << endl;
throw ;
}
}
catch(...)
{
cout << "outer: catch(...)" << endl;
}
}
int main()
{
Demo();
return 0;
}
輸出結(jié)果:
Inner: catch(...)
outer: catch(...)
編程說(shuō)明:異常的重新解釋示例2
#include <iostream>
#include <string>
using namespace std;
/*
假設(shè): 當(dāng)前的函數(shù)是第三方庫(kù)中的函數(shù)系奉,因此企软,我們無(wú)法修改源代碼
函數(shù)名: void func(int i)
拋出異常信息: int
-1 --> 參數(shù)異常
-2 --> 運(yùn)行異常
-3 --> 超時(shí)異常
*/
void func(int i)
{
if( i < 0 )
{
throw -1;
}
if( i > 100 )
{
throw -2;
}
if( i == 11 )
{
throw -3;
}
cout << "Run func ..." << endl;
}
void MyFunc(int i)
{
try
{
func(i);
}
catch(int i)
{
switch(i)
{
case -1:
throw "Invalid Parameter";
break;
case -2:
throw "Runtime Exception";
break;
case -3:
throw "Timeout Exception";
break;
}
}
catch(...)
{
throw ;
}
}
int main()
{
try
{
MyFunc(11);
}
catch(const char* cs)
{
cout << "Exception Info: " << cs << endl;
}
catch(...)
{
cout << "Unknown Exception!!!" << endl;
}
return 0;
}
輸出結(jié)果
Exception Info: Timeout Exception
2. 自定義異常類(lèi)
- 異常的類(lèi)型可以是自定義類(lèi)類(lèi)型
- 對(duì)于類(lèi)類(lèi)型異常的匹配依舊是至上而下嚴(yán)格匹配
- 賦值兼容性原則在異常匹配中依然適用矮瘟,即子類(lèi)的異常情況可以被父類(lèi)的異常語(yǔ)句塊catch到
- 一般原則:
- 匹配子類(lèi)異常的catch放在上部
- 匹配父類(lèi)異常的catch放在下部
- 在工程中會(huì)定義一系列的異常類(lèi)
- 每個(gè)類(lèi)代表工程中可能出現(xiàn)的一種異常類(lèi)型
- 代碼復(fù)用時(shí)可能需要重解釋不同點(diǎn)的異常類(lèi)
- 在定義
catch
語(yǔ)句塊時(shí)推薦使用引用作為參數(shù)瞳脓,可以避開(kāi)拷貝構(gòu)造,提高程序效率
編程說(shuō)明:類(lèi)類(lèi)型的異常
#include <iostream>
#include <string>
using namespace std;
class Base
{
};
class Exception : public Base
{
int m_id;
string m_desc;
public:
Exception(int id, string desc)
{
m_id = id;
m_desc = desc;
}
int id() const
{
return m_id;
}
string description() const
{
return m_desc;
}
};
/*
假設(shè): 當(dāng)前的函數(shù)是第三方庫(kù)中的函數(shù)澈侠,因此劫侧,我們無(wú)法修改源代碼
函數(shù)名: void func(int i)
拋出異常信息: int
-1 --> 參數(shù)異常
-2 --> 運(yùn)行異常
-3 --> 超時(shí)異常
*/
void func(int i)
{
if( i < 0 )
{
throw -1;
}
if( i > 100 )
{
throw -2;
}
if( i == 11 )
{
throw -3;
}
cout << "Run func ..." << endl;
}
void MyFunc(int i)
{
try
{
func(i);
}
catch(int i)
{
switch(i)
{
case -1:
throw Exception(-1, "Invalid Parameter");
break;
case -2:
throw Exception(-2, "Runtime Exception");
break;
case -3:
throw Exception(-3, "Timeout Exception");
break;
}
}
catch(...)
{
throw ;
}
}
int main()
{
try
{
MyFunc(11);
}
catch(const Exception& e)
{
cout << "Exception Info: " << endl;
cout << " Id: " << e.id() << endl;
cout << " Description: " << e.description() << endl;
}
catch(...)
{
cout << "Unknown Exception!!!" << endl;
}
return 0;
}
輸出結(jié)果:
Exception Info:
Id: -3
Description: Timeout Exception
3. STL中的異常類(lèi)
- C++標(biāo)準(zhǔn)庫(kù)(STL)中提供了實(shí)用異常類(lèi)族
- SLT中的異常都是從
exception
類(lèi)派生的 -
exception
類(lèi)有兩個(gè)主要的分支:-
logic_error
:常用于程序中的可避免邏輯錯(cuò)誤 -
runtime_error
:常用于程序中無(wú)法避免的惡性錯(cuò)誤
-
編程說(shuō)明:STL中的異常使用
補(bǔ)充
4. 小結(jié)
-
catch
語(yǔ)句塊中可以拋出異常 - 異常的類(lèi)型可以是自定義類(lèi)類(lèi)型
- 賦值兼容性原則在異常匹配中依然適用
- 標(biāo)準(zhǔn)庫(kù)中的異常都是從
exception
類(lèi)派生的