鍍金池/ 教程/ C/ 異常處理
動(dòng)態(tài)內(nèi)存
類和對(duì)象
接口 (抽象類)
結(jié)構(gòu)體
循環(huán)的類型
函數(shù)
數(shù)字
日期和時(shí)間
基本語法
多態(tài)
數(shù)據(jù)抽象
注釋
命名空間
字符串
預(yù)處理器
決策語句
修飾符的類型
鍙橀噺綾誨瀷
基本輸入輸出
操作符
數(shù)組
模板
多線程
繼承
Web 編程
信號(hào)處理
指針
存儲(chǔ)類型
概述
引用
常量
異常處理
開發(fā)環(huán)境
重載
變量作用域
數(shù)據(jù)類型
數(shù)據(jù)封裝
文件和流

異常處理

異常是一個(gè)程序執(zhí)行過程中出現(xiàn)的問題。C++ 異常是對(duì)程序運(yùn)行過程中產(chǎn)生的例外情況作出的響應(yīng),比如試圖除以零。

異常提供一種方法將程序控制從一個(gè)程序的一部分轉(zhuǎn)移到另一部分。C++ 異常處理是建立在三個(gè)關(guān)鍵詞: 嘗試,捕獲和拋出之上的。

  • throw: 程序運(yùn)行出現(xiàn)問題時(shí)拋出異常。這是使用一個(gè) throw 關(guān)鍵字實(shí)現(xiàn)的。
  • catch: 程序用異常處理器在你想要處理問題的地方捕獲異常。catch 關(guān)鍵字顯示異常的捕獲。
  • try: 一個(gè) try 塊標(biāo)識(shí)一個(gè)可能會(huì)產(chǎn)生異常的代碼塊。緊隨其后的是一個(gè)或多個(gè) catch 塊。

假設(shè)一個(gè)代碼塊將產(chǎn)生一個(gè)異常,結(jié)合使用 try 和 catch 關(guān)鍵詞的方法捕獲了一個(gè)異常。一個(gè) try / catch 塊放置在可能生成一個(gè)異常的代碼周圍。在一個(gè) try / catch 塊里面的代碼被稱為保護(hù)代碼, try / catch 的語法規(guī)則如下:

    try
    {
       // protected code
    }catch( ExceptionName e1 )
    {
       // catch block
    }catch( ExceptionName e2 )
    {
       // catch block
    }catch( ExceptionName eN )
    {
       // catch block
    }

你可以列出多個(gè)捕捉語句捕獲不同類型的異常, 以防你的 try 代碼塊在不同的情況下產(chǎn)生了不止一個(gè)異常。

拋出異常

異??梢栽诖a塊的任何地方使用拋出語句拋出。把語句的操作數(shù)確定類型的異常,可以是任何表達(dá)式,表達(dá)式的結(jié)果的類型決定了類型的異常拋出。

下面是一個(gè)例子, 在除以零條件發(fā)生時(shí),拋出異常:

    double division(int a, int b)
    {
       if( b == 0 )
       {
      throw "Division by zero condition!";
       }
       return (a/b);
    }

捕獲異常

try 塊后的 catch 塊可以捕獲任何異常。您可以指定你需要捕獲何種類型的異常,這是由出現(xiàn)在關(guān)鍵字 catch 后邊的括號(hào)中的異常聲明確定的。

    try
    {
       // protected code
    }catch( ExceptionName e )
    {
      // code to handle ExceptionName exception
    }

上面的代碼將捕獲到一個(gè) ExceptionName 類型的異常。如果您想要指定一個(gè) catch 塊可以應(yīng)該處理任何在 try 代碼中產(chǎn)生的異常,你必須將一個(gè)省略號(hào)…放在 catch 后的括號(hào)中,異常聲明如下:

    try
    {
       // protected code
    }catch(...)
    {
      // code to handle any exception
    }

下面是一個(gè)例子,這個(gè)例子拋出會(huì)除零異常, 我們在 catch 塊里面捕獲它

    #include <iostream>
    using namespace std;

    double division(int a, int b)
    {
       if( b == 0 )
       {
      throw "Division by zero condition!";
       }
       return (a/b);
    }

    int main ()
    {
       int x = 50;
       int y = 0;
       double z = 0;

       try {
     z = division(x, y);
     cout << z << endl;
       }catch (const char* msg) {
     cerr << msg << endl;
       }

       return 0;
    }

因?yàn)樯侠刑岢隽艘粋€(gè) const char *類型的異常, 所以捕捉這個(gè)異常時(shí),我們必須在 catch 塊中使用const char *。如果我們編譯和運(yùn)行上面的代碼, 這將產(chǎn)生以下結(jié)果:

    Division by zero condition!

C++ 標(biāo)準(zhǔn)異常

C++ 在 <exception> 中提供了一系列標(biāo)準(zhǔn)的異常,我們可以用在我們的程序中。這些異常使用父-子分層結(jié)構(gòu)展示如下:

http://wiki.jikexueyuan.com/project/cplusplus/images/cpp_exceptions.jpg" alt="" />

這是對(duì)上面提到的層次結(jié)構(gòu)中每個(gè)異常的描述:

異常 描述
std::exception 異常和所有標(biāo)準(zhǔn) C++ 異常的父類
std::bad_alloc 該異常可能會(huì)在使用 new 關(guān)鍵字時(shí)拋出。
std::bad_cast 該異??梢杂?dynamic_cast 拋出。
std::bad_exception 這是一個(gè)在 C++ 程序中處理意想不到的異常的有效手段。
std::bad_typeid 該異常可以由 typeid 拋出。
std::logic_error 理論上可以通過閱讀代碼發(fā)現(xiàn)的異常。
std::domain_error 這是一個(gè)在數(shù)學(xué)無效域被使用時(shí)拋出的異常。
std::invalid_argument 參數(shù)非法時(shí)會(huì)拋出的異常。
std::length_error 太大的 std::string 被創(chuàng)造時(shí),拋出異常。
std::out_of_range 可以拋出該異常的方法例如 std::vector 和 std::bitset ::operator[] ()。
std::runtime_error 理論上不能通過讀代碼檢測到的異常。
std::overflow_errorr 如果出現(xiàn)數(shù)字溢出,則拋出該異常
std::range_error 當(dāng)你試圖存儲(chǔ)一個(gè)超過范圍的值的時(shí)候,會(huì)拋出該異常。
std::underflow_error 如果出現(xiàn)數(shù)學(xué)下溢時(shí),拋出該異常。

定義新異常

你可以采用繼承及重寫異常類來。下面是示例, 顯示如何使用 std::exception 類以標(biāo)準(zhǔn)的方式實(shí)現(xiàn)自己的異常:

    #include <iostream>
    #include <exception>
    using namespace std;

    struct MyException : public exception
    {
      const char * what () const throw ()
      {
    return "C++ Exception";
      }
    };

    int main()
    {
      try
      {
    throw MyException();
      }
      catch(MyException& e)
      {
    std::cout << "MyException caught" << std::endl;
    std::cout << e.what() << std::endl;
      }
      catch(std::exception& e)
      {
    //Other errors
      }
    }

這將產(chǎn)生如下的結(jié)果:

    MyException caught
    C++ 

這里,what() 是一個(gè)異常類提供的公共方法,所有子異常類都覆蓋了該方法。這將返回一個(gè)異常的原因。

上一篇:數(shù)組下一篇:類和對(duì)象