摘自:http://www.dewen.net.cn/q/8659
C++語言本身或標準程序庫所拋出的所有異常,都派生自基類exception。這是其他數個標準異常類別的基類,它們共同構成一個類體系:
這些標準異常類別分爲三組:
(1)語言本身所支持的異常
此類異常用以支撐某些語言特性。主要包括:
bad_alloc:new操作失敗會拋出。
bad_cast:執行期間加在一個引用上面的動態性型別轉換操作失敗時拋出。
bad_typeid:執行RTTI時,交給typeid的參數爲零或空指針時拋出
bad_exception:非預期的異常
(2)C++標準程序庫發出的異常
總是派生自logic_error。邏輯錯誤是由於程序內部邏輯而導致的錯誤。邏輯錯誤是可以避免的,且在程序開始執行之前,能夠被檢測到。
C++標準庫中定義的邏輯錯誤如下:
class logic_error : public exception {
public:
explicit logic_error (const string& what_arg);
};
class invalid_argument : public logic_error {
public:
explicit invalid_argument (const string& what_arg);
};
class out_of_range : public logic_error {
public:
explicit out_of_range (const string& what_arg);
};
class length_error : public logic_error {
public:
explicit length_error (const string& what_arg);
};
class domain_error : public logic_error {
public:
explicit domain_error (const string& what_arg);
};
錯誤分類解釋及舉例:
domain_error:專業領域內的範疇 invalid_argument:無效參數,比如講bitset以char而非0或1進行初始化 length_error:可能超越了最大極限,比如對着某個字符串附加太多字符。 out_of_range:參數不再預期範圍內。例如在諸如array的容器或字符串string中採用一個錯誤索引。
(3)程序作用域之外發出的異常
總是派生自runtime_error,用來指出“不在程序範圍內,且不容易迴避”的事件。此類錯誤只在程序執行時纔是可檢測的。C++標準庫中的定義如下:
class runtime_error : public exception {
public:
explicit runtime_error (const string& what_arg);
};
class range_error : public runtime_error {
public:
explicit range_error (const string& what_arg);
};
class overflow_error : public runtime_error {
public:
explicit overflow_error (const string& what_arg);
};
class underflow_error : public runtime_error {
public:
explicit underflow_error (const string& what_arg);
};
range_error:內部計算時發生區間錯誤
overflow_error:算數運算時發生上溢
underflow_error:算數運算時發生下溢
Update:
實例代碼:
#include <iostream>
#include <string>
#include <bitset>
#include <typeinfo>
#include <vector>
#include <stdexcept>
using namespace std;
//自定義配置器,vector分配空間使用
template<class _Ty>
class stingyallocator : public allocator<_Ty>
{
public:
template <class U>
struct rebind {
typedef stingyallocator<U> other;
};
size_t max_size( ) const
{
return 10;
};
};
int main()
{
//邏輯錯誤:out_of_range
try {
string str( "Micro" );
string rstr( "soft" );
str.append( rstr, 5, 3 );
cout << str << endl;
}
catch ( exception &e ) {
cerr << "Caught: " << e.what( ) << endl;
cerr << "Type: " << typeid( e ).name( ) << endl << endl;
};
//邏輯錯誤:length_error
try
{
vector<int, stingyallocator< int > > myv;
for ( int i = 0; i < 11; i++ )
myv.push_back( i );
}
catch ( exception &e )
{
cerr << "Caught " << e.what( ) << endl;
cerr << "Type " << typeid( e ).name( ) << endl << endl;
};
//邏輯錯誤:invalid_argument
try
{
bitset< 32 > bitset( string( "11001010101100001b100101010110000") );
}
catch ( exception &e )
{
cerr << "Caught " << e.what( ) << endl;
cerr << "Type " << typeid( e ).name( ) << endl << endl;
};
//邏輯錯誤:domain_error
try
{
throw domain_error( "Your domain is in error!" );
}
catch (exception &e)
{
cerr << "Caught: " << e.what( ) << endl;
cerr << "Type: " << typeid(e).name( ) << endl << endl;
};
//運行時錯誤:range_error
try
{
throw range_error( "The range is in error!" );
}
catch (exception &e)
{
cerr << "Caught: " << e.what( ) << endl;
cerr << "Type: " << typeid( e ).name( ) << endl << endl << endl;
};
//運行時錯誤:underflow_error
try
{
throw underflow_error( "The number's a bit small, captain!" );
}
catch ( exception &e ) {
cerr << "Caught: " << e.what( ) << endl;
cerr << "Type: " << typeid( e ).name( ) << endl << endl;
};
//運行時錯誤:overflow_error
try
{
bitset< 33 > bitset;
bitset[32] = 1;
bitset[0] = 1;
unsigned long x = bitset.to_ulong( );
}
catch(exception &e)
{
cerr << "Caught " << e.what() << endl;
cerr << "Type: " << typeid(e).name() << endl << endl;
}
return 0;
}
運行結果:
推薦參考資料:
【1】《C++Primer(第三版)》第855頁 19.2.8C++標準的異常類層次結構
【2】《C++標準程序庫》第25頁 3.3 錯誤處理和異常處理
【3】Confused about std::runtime_error vs. std::logic_error
【4】C++中異常類的使用方法