技術文章翻譯(一) -- C++異常處理機制

本人聲明

1.本欄僅爲歸檔自己看到的優秀文章;
2.文章版權歸原作者所有;
3.因爲個人水平有限,翻譯難免有錯誤,請多多包涵。

原文地址

https://www.codeguru.com/columns/kate/c-exception-handling-how-to-handle-exceptions-in-c.html

文章正文

C++異常處理機制

– 作者:Manoj Debnath 發表於:2017.03.24
異常是指不符合規則或者不符合常理的情況。它表示程序執行期間可能出現了問題。異常處理機制提供了一種方法,該方法能夠將程序控制權和相關信息從程序執行點轉移到異常處理的位置。處理程序爲程序員提供了一個機會窗口,該窗口可以順利地終止或以適當的方式處理異常。本文給出了C ++中實現異常處理機制的基本思路。

  • 概述

程序是從執行某項具體任務開始的。如果執行指定任務的代碼順利運行,則繼續執行下一個任務,依此類推,直到程序完成全部功能。現在,如果在執行過程中出現任何錯誤,代碼將會進入到錯誤處理例程。錯誤處理邏輯與正常的程序邏輯是混合在一起的,並且會交叉執行。雖然這種混合的形式很好,但它會使得代碼變得難以閱讀、維護和調試;即使對於規模不是很大的程序,這種情況也依然存在。

請注意,C語言中提供錯誤處理機制還是非常原始的。這是因爲C語言本身對其沒有直接的支持。因此,我們在這裏只能採用比較低級的方式–通過函數返回值來判斷。通常來說,如果函數返回負值或NULL,則表示函數發生了錯誤。有時候,我們會定義一個名爲errno的全局變量,該變量作爲函數調用期間的錯誤指示符。頭文件error.h則定義了許多具體的錯誤代碼。

使用異常處理機制,不僅可以提高程序的清晰度,而且能夠利用異常處理和程序邏輯分離的方式來降低代碼的複雜度。我們可以分別處理它們。這帶來了巨大的靈活性;除此之外,我們可以決定處理哪些異常,並將它們按照相關類型分組處理,或者完全不進行處理。

  • C++中的異常處理機制
    C ++異常處理是包含在try … catch塊中的。 try塊包含着可能會發生異常的代碼段。它跟在關鍵字try後的大括號裏。如果發生異常,它將由專門捕獲和處理異常的catch語句塊處理。 catch也是一個關鍵字,後跟大括號。每個try塊都至少附帶一個緊跟其後的catch處理程序。一個try塊也可能關聯多個catch處理程序。在這種情況下,一旦發生異常時,程序會選擇與其異常類型匹配的catch處理程序作爲最終的處理程序。匹配是基於拋出的異常類型或者其繼承的基類類型來進行的。

  • 下面的例子用於說明異常處理的基本思想:

#ifndef DIVISIONBYZEROEXCEPTION_H_
#define DIVISIONBYZEROEXCEPTION_H_

#include <stdexcept>
using namespace std;

class DivisionByZeroException :public runtime_error{
public:
   DivisionByZeroException():runtime_error
      ("divide by zero exception occurred"){};
};

#endif /* DIVISIONBYZEROEXCEPTION_H_ */


#include <iostream>
#include "DivisionByZeroException.h"
using namespace std;

double div(int num, int denom) {
   if (denom == 0)
      throw DivisionByZeroException();
   return static_cast<double>(num) / denom;
}

int main() { 
   int n1, n2;
   double result;
   cout << "Enter two number: ";
   cin >> n1 >> n2;
   try {
      cout << "The result is " << div(n1, n2) << endl;
   } catch (DivisionByZeroException &ex) {
      cerr << "Excetion: " << ex.what() << endl;
   }
   return 0;
}

異常旨在處理同步錯誤,例如數組的索引越界,除以零,算術溢出,無法分配內存等錯誤。異常處理機制無法處理異步錯誤,例如鍵盤和鼠標中斷,網絡消息接收,I / O操作等錯誤。這是因爲這些事件是並行發生的,與程序控制流無關。

-重新拋出異常
程序可以決定部分處理異常或者根本不處理異常。在這種情況下,它可以將處理責任傳遞給其他處理程序。

void func1() {
   try {
      throw exception();
   } catch (exception &) {
      throw;
   }
}

int main() {
   try {
      func1();
   } 
   catch (exception &) {
   }
   return 0;
}

函數func1是在main程序的try塊內調用的。函數func1還包含一個try … catch塊。 throw語句拋出一個標準庫中的異常類實例。catch處理程序(func1)捕獲此異常並再次拋出它,然後由main中定義的catch塊捕獲。 main中的catch塊對此異常並沒有做任何處理,之後程序便結束了。

  • 異常說明

我們可以爲一個函數指定一個可能拋出的異常列表。

void func1() throw(Exception1, Exception2,
      Exception3){
   // ...
}

此函數只能拋出throw列表中指定的異常。如果出現了不屬於throw列表中指定的異常,則異常處理機制將調用意外處理函數並終止該程序的執行。然而,如果我們不提供throw列表,它會自動調用意外處理函數。(我們可以使用set_unexpected函數來自定義意外處理函數的具體行爲。有關此內容的更多信息,請參閱C ++標準文檔)。

void func1() throw(){
   // ...
}
  • 結論
    對於大多數現代編程語言來說,異常處理機制是其一項基本功能。有些語言(例如Java),從一開始就強調了這一點。因此,異常處理機制的使用是很普遍的。另一方面,C++語言是基於C語言發展的,異常處理機制是後來添加上的。此外,必須以這樣的方式來利用異常處理能力,這樣才能夠不干擾已經存在的絕大多數代碼,同時充分利用該機制的優點。因此,在將異常處理的設計決策納入實際實現之前,需要考慮幾個重要方面。 Andrew Koenig和Bjarne Stroustrup撰寫的關於C ++異常處理的文章介紹了相關基本知識,並提供了一些關於異常處理機制的重要見解。

  • 參考文獻
    Exception Handling for C++ by Andrew Koenig and Bjarne Stroustrup

  • 關於作者
    Manoj Debnath
    [email protected]

  • 相關文章
    Last.fm Open Sources C++ Moost Library Now Available
    CppDepend Pro License for C\C++ open source project contributors

欄目導航
上一篇:無
下一篇:技術文章翻譯(二) – 一種簡單的解決方案:使用Visual Studio Code編寫C和C ++代碼

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