C++标准异常类

来源:互联网 发布:arrayremove php 编辑:程序博客网 时间:2024/05/15 21:50


C++语言本身或标准程序库所抛出的所有异常,都派生自基类exception。这是其他数个标准异常类别的基类,它们共同构成一个类体系:


图一 标准异常阶层体系

这些标准异常类别分为三组:


(1)语言本身所支持的异常

此类异常用以支撑某些语言特性。主要包括:
bad_alloc:new操作失败会抛出。
bad_cast:执行期间加在一个引用上面的动态性型别转换操作失败时抛出。
bad_typeid:执行RTTI时,交给typeid的参数为零或空指针时抛出
bad_exception:非预期的异常


(2)C++标准程序库发出的异常

总是派生自logic_error。逻辑错误是由于程序内部逻辑而导致的错误。逻辑错误是可以避免的,且在程序开始执行之前,能够被检测到。
C++标准库中定义的逻辑错误如下:

[cpp] view plaincopyprint?
  1. <span style="font-family: KaiTi_GB2312;">class logic_error : public exception {  
  2. public:  
  3.   explicit logic_error (const string& what_arg);  
  4. };  
  5.   
  6. class invalid_argument : public logic_error {  
  7. public:  
  8.   explicit invalid_argument (const string& what_arg);  
  9. };  
  10.   
  11. class out_of_range : public logic_error {  
  12. public:  
  13.   explicit out_of_range (const string& what_arg);  
  14. };  
  15.   
  16. class length_error : public logic_error {  
  17. public:  
  18.   explicit length_error (const string& what_arg);  
  19. };  
  20.   
  21. class domain_error : public logic_error {  
  22. public:  
  23.   explicit domain_error (const string& what_arg);  
  24. };</span>  


错误分类解释及举例:

domain_error:专业领域内的范畴 

invalid_argument:无效参数,比如讲bitset以char而非0或1进行初始化

length_error:可能超越了最大极限,比如对着某个字符串附加太多字符。 

out_of_range:参数不再预期范围内。例如在诸如array的容器或字符串string中采用一个错误索引。


(3)程序作用域之外发出的异常

总是派生自runtime_error,用来指出“不在程序范围内,且不容易回避”的事件。此类错误只在程序执行时才是可检测的。C++标准库中的定义如下:

[cpp] view plaincopyprint?
  1. <span style="font-family: KaiTi_GB2312;">class runtime_error : public exception {  
  2. public:  
  3.   explicit runtime_error (const string& what_arg);  
  4. };  
  5.   
  6. class range_error : public runtime_error {  
  7. public:  
  8.   explicit range_error (const string& what_arg);  
  9. };  
  10.   
  11. class overflow_error : public runtime_error {  
  12. public:  
  13.   explicit overflow_error (const string& what_arg);  
  14. };  
  15.   
  16. class underflow_error : public runtime_error {  
  17. public:  
  18.   explicit underflow_error (const string& what_arg);  
  19. };</span>  


range_error:内部计算时发生区间错误

overflow_error:算数运算时发生上溢

underflow_error:算数运算时发生下溢



实例代码:

[cpp] view plaincopyprint?
  1. <span style="font-family: KaiTi_GB2312;">#include <iostream>  
  2. #include <string>  
  3. #include <bitset>  
  4. #include <typeinfo>  
  5. #include <vector>  
  6. #include <stdexcept>  
  7.   
  8. using namespace std;  
  9.   
  10. //自定义配置器,vector分配空间使用  
  11. template<class _Ty>  
  12. class stingyallocator : public allocator<_Ty>  
  13. {  
  14. public:  
  15.    template <class U>  
  16.     struct rebind {  
  17.           typedef stingyallocator<U> other;  
  18.     };  
  19.   
  20.    size_t max_size( ) const  
  21.    {  
  22.          return 10;  
  23.    };  
  24. };  
  25.   
  26. int main()  
  27. {  
  28.     //逻辑错误:out_of_range  
  29.     try {  
  30.       string str( "Micro" );  
  31.       string rstr( "soft" );  
  32.       str.append( rstr, 5, 3 );  
  33.       cout << str << endl;  
  34.    }  
  35.    catch ( exception &e ) {  
  36.       cerr << "Caught: " << e.what( ) << endl;  
  37.       cerr << "Type: " << typeid( e ).name( ) << endl << endl;  
  38.    };  
  39.   
  40.    //逻辑错误:length_error  
  41.    try  
  42.    {  
  43.       vector<int, stingyallocator< int > > myv;  
  44.       for ( int i = 0; i < 11; i++ )  
  45.         myv.push_back( i );  
  46.    }  
  47.    catch ( exception &e )  
  48.    {  
  49.       cerr << "Caught " << e.what( ) << endl;  
  50.       cerr << "Type " << typeid( e ).name( ) << endl << endl;  
  51.    };  
  52.   
  53.    //逻辑错误:invalid_argument  
  54.    try  
  55.    {  
  56.       bitset< 32 > bitset( string( "11001010101100001b100101010110000") );  
  57.    }  
  58.    catch ( exception &e )  
  59.    {  
  60.       cerr << "Caught " << e.what( ) << endl;  
  61.       cerr << "Type " << typeid( e ).name( ) << endl << endl;  
  62.    };  
  63.   
  64.    //逻辑错误:domain_error  
  65.    try  
  66.    {  
  67.       throw domain_error( "Your domain is in error!" );  
  68.    }  
  69.    catch (exception &e)  
  70.    {  
  71.       cerr << "Caught: " << e.what( ) << endl;  
  72.       cerr << "Type: " << typeid(e).name( ) << endl << endl;  
  73.    };  
  74.   
  75.    //运行时错误:range_error  
  76.     try  
  77.    {  
  78.       throw range_error( "The range is in error!" );  
  79.    }  
  80.    catch (exception &e)  
  81.    {  
  82.       cerr << "Caught: " << e.what( ) << endl;  
  83.       cerr << "Type: " << typeid( e ).name( ) << endl << endl << endl;  
  84.    };  
  85.   
  86.    //运行时错误:underflow_error  
  87.    try  
  88.    {  
  89.       throw underflow_error( "The number's a bit small, captain!" );  
  90.    }  
  91.    catch ( exception &e ) {  
  92.       cerr << "Caught: " << e.what( ) << endl;  
  93.       cerr << "Type: " << typeid( e ).name( ) << endl << endl;  
  94.    };  
  95.   
  96.     //运行时错误:overflow_error  
  97.     try  
  98.     {  
  99.         bitset< 33 > bitset;  
  100.         bitset[32] = 1;  
  101.         bitset[0] = 1;  
  102.         unsigned long x = bitset.to_ulong( );  
  103.     }  
  104.     catch(exception &e)  
  105.     {  
  106.         cerr << "Caught " << e.what() << endl;  
  107.         cerr << "Type: " << typeid(e).name() << endl << endl;  
  108.     }  
  109.   
  110.     return 0;  
  111. }</span>  



运行结果(CodeBlocks):



参考资料: 

C++中异常类的使用方法

Confused about std::runtime_error vs. std::logic_error

0 0
原创粉丝点击