c++中異常處理中:logic_error、runtime_error

摘自: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++中異常類的使用方法


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章