1. 程式人生 > >簡記c、c++、java異常處理機制的區別

簡記c、c++、java異常處理機制的區別

一、C異常處理:用於多層返回的setjmp/longjmp機制

C中的異常處理是通過setjmp.h標頭檔案中定義的巨集setjmp和巨集longjmp實現的。

類似於退棧,setjmp/longjmp機制的使用方法:

  1. 在希望進行錯誤處理的位置用setjmp巨集進行標註                              把當前的“環境”(函式堆疊和暫存器)以陣列方式儲存
  2. 在可能出現錯誤的地方使用longjmp巨集進行控制轉移                 恢復儲存的“環境”並將執行位置轉回setjmp語句的下一句

典型方法:

#include <iostream>
#include <csetjmp>
#include <cstdlib>

using namespce std;

static jmp_buf env;  //jmp_buf型別的物件用於儲存“環境”

void f( int );
int main()
{
   /*setjmp()第一次被呼叫時返回0,若是longjmp()導致的控制返回,ret會被重置為longjmp()的第二個引數。

   int ret = setjmp( env);
   if(1 == ret)
   {
       cout<<"這裡是異常處理"<<endl;
       exit(0);
    }
    f(0);
    return 0;
}

void f(int j)
{
   for(;j<6;j++)
   {
      if(3==j)
        longjmp(env,1);
    }
}

二、C++異常處理:try--catch--throw

雖然C++中也可以使用C的方法,但是這樣做會出很多問題,例如會跳過類解構函式的呼叫,並且setjmp()的開銷較大(儲存的資訊)

其實通過字面意思就差不多可以理解用法了:

  1. 將要檢查的語句放在try{}中
  2. 在try{}模組中加入throw,即要丟擲的異常
  3. 在try{}模組後加上catch{}模組捕捉異常

典型方法:


#include <iostream>
#include <cstdlib>
using namespce std;

class MyException{};

void f(int)throw(MyException);       // throw(MyException)是可選的;(比之於java),如果throw(),則表示不丟擲任何異常

int main()
{
  try{
       f(0);
       }
  catch(MyException &e){             // 引數列表裡可以只有型別,不包括物件(比之於java)
      cout<<"捕捉到異常";
   }
  return 0;
}

void f(int j)throw(MyException)
{
  throw MyException();
}

補充:

(1)try和catch塊中必須要用花括號括起來,即使花括號內只有一個語句也不能省略花括號;

(2)try和catch必須成對出現,一個try_catch結果中只能有一個try塊,但可以有多個catch塊,以便與不同的異常資訊匹配;

(3)如果在catch塊中沒有指定異常資訊的型別,而用刪節號"...",則表示它可以捕獲任何型別的異常資訊;

(4)如果throw不包括任何表示式,表示它把當前正在處理的異常資訊再次丟擲,傳給其上一層的catch來處理;

(5)C++中一旦丟擲一個異常,如果程式沒有任何的捕獲,那麼系統將會自動呼叫一個系統函式terminate,由它呼叫abort終止程式;

三、java異常處理:try--catch--throw--finally

與C++的異常處理語法相似,java的異常處理在字面”上看,只比C++多了個finally,但是細節上還是有許多不同

用法:

  1. try{}模組                                        放入要檢查的語句
  2. 放入throw語句                             要丟擲的異常
  3. catch{}模組                              捕捉異常
  4. finally{}模組                             無論是否丟擲異常,都要執行這一模組,無論如何,最後都要執行finally模組
典型方法:
class MyException extends Exception{}
class Test{
static void f() throws MyException{} //注意此處throws MyException 為必須的(比之於C++),且,java用的throws,而C++是throw
public static void main( String[] args {
try{
f();
}
catch(MyException e){ //catch必須顯式的指出引數物件
system.out.println("捕捉到異常");
}
finally{
system.out.println("這裡是finally模組");

}
}

補充:

java中還有unchecked異常機制,異常的型別為RuntimeException或Error的子類,此類異常可以不必在try--catch程式碼塊中丟擲,可以直接丟擲,且,其被系統捕獲導致程式終止

四、一些額外的c++與java的比較

  1. C++可以丟擲所有型別的物件,而java只能丟擲Throwable的子類
  2. java中若要丟擲異常必須在函式頭部宣告,而C++中只是推薦採用此方式
  3. java在catch模組中必須顯式的制定一個異常引數物件,而C++不是必須的

五、C與C++的堆疊解退比較

假設都是在main函式中遞迴呼叫函式f(int),f(3)會導致異常

此為C:


此為C++: