天天看點

C++中異常類的使用方法

C++有很多的标準異常類:

namespace std

{

    //exception派生

    class logic_error; //邏輯錯誤,在程式運作前可以檢測出來

    //logic_error派生

    class domain_error; //違反了前置條件

    class invalid_argument; //指出函數的一個無效參數

    class length_error; //指出有一個超過類型size_t的最大可表現值長度的對象的企圖

    class out_of_range; //參數越界

    class bad_cast; //在運作時類型識别中有一個無效的dynamic_cast表達式

    class bad_typeid; //報告在表達試typeid(*p)中有一個空指針p

    //exception派生

    class runtime_error; //運作時錯誤,僅在程式運作中檢測到

    //runtime_error派生

    class range_error; //違反後置條件

    class overflow_error; //報告一個算術溢出

    class bad_alloc; //存儲配置設定錯誤

}

     請注意觀察上述類的層次結構,可以看出,标準異常都派生自一個公共的基類exception。基類包含必要的多态性函數提供異常描述,可以被重載。下面是exception類的原型:

class exception

{

public:

    exception() throw();

    exception(const exception& rhs) throw();

    exception& operator=(const exception& rhs) throw();

    virtual ~exception() throw();

    virtual const char *what() const throw();

};

    其中的一個重要函數為what(),它傳回一個表示異常的字元串指針。

    标準庫異常類定義在以下四個頭檔案中

    1、exception頭檔案:定義了最常見的标準異常類,其類名為exception。隻通知異常的産生,但不會提供更多的資訊

    2、stdexcept頭檔案定義了以下幾種常見異常類

   函數                                                     功能或作用

exception                                                最常見的問題

runtime_error                                          運作時錯誤:僅在運作時才能檢測到的問題

range_error                                             運作時錯誤:生成的結果超出了有意義的值域範圍

overflow_error                                        運作時錯誤:計算上溢

underflow_error                                      運作時錯誤:計算下溢

logic_error                                                邏輯錯誤:可在運作前檢測到的問題

domain_error                                          邏輯錯誤:參數的結果值不存在

invalid_argument                                    邏輯錯誤:不合适的參數

length_error                                             邏輯錯誤:試圖生成一個超出該類型最大長度的對象

out_of_range                                            邏輯錯誤:使用一個超出有效範圍的值

    3、new頭檔案定義了bad_alloc異常類型,提供因無法配置設定記憶體而由new抛出的異常

    4、type_info頭檔案定義了bad_cast異常類型(要使用type_info必須包含typeinfo頭檔案)

    下面是使用異常類的例子:

    首先,我定義了幾個異常類,這些類也可以從标準異常類進行派生,如下

class BadInitializers

{

public:

 BadInitializers() {}

};

class OutOfBounds

{

public:

 OutOfBounds(int i) { cout<<"Size "<<i<<" is illegal!!!"<<endl; }

};

class SizeMismatch

{

public:

 SizeMismatch() {}

};

然後要在程式中需要的地方使用throw來抛出異常類,兩個抛出異常類的例子如下

template <class T>

Array1D<T>::Array1D(int sz)

{

 if(sz<0)

 {

    //throw BadInitializers();

    throw invalid_argument("Size has to be bigger than 0!!!");

 }

 size=sz;

 element=new T[size];

}

template <class T>

T &Array1D<T>::operator[](int i) const

{

 if(i<0||i>=size)

 {

  throw OutOfBounds(i);

 }

 return element[i];

}

然後在主程式中使用try...catch...來捕獲異常,并進行相應的處理,如下

try

 {

  int i=0;

  Array1D<int> a1(5);

  a1[0]=1;

  a1[1]=3;

  a1[2]=5;

  a1[3]=7;

  a1[4]=8;

  Array1D<int> a2(a1);

  for(i=0;i<a2.Size();i++)

  {

   cout<<a2[i]<<" ";

  }

  cout<<endl;

  Array1D<int> a3(5);

  a3=a1+a2;

  cout<<a3;

   }

 catch(BadInitializers)

 {

  cout<<"Error:BadInitializers!!!"<<endl;

 }

 catch(OutOfBounds &e)

 {

  cout<<"Error:OutOfBounds!!!"<<endl;

 }

 catch(SizeMismatch &e)

 {

  cout<<"Error:SizeMismatch!!!"<<endl;

 }

 catch(invalid_argument &e)

 {

  cout<<"Error:"<<e.what()<<endl;

 }

 catch(...)

 {

  cout<<"An unknown error!!!"<<endl;

 }