搜尋
  • 登入
  • 報名
密碼重置成功

關注您感興趣的項目並了解有關它們的最新消息

C++ 例外處理

收藏 154
閱讀 53378
更新時間 2016-09-11

異常是程式在執行期間產生的問題。 C++ 異常是指在程式執行時發生的特殊情況,例如嘗試除以零的操作。

異常提供了一種轉移程式控制權的方式。 C++ 例外處理涉及到三個關鍵字:try、catch、throw

  • throw: 當問題出現時,程式會拋出一個例外。這是透過使用 throw 關鍵字來完成的。

  • catch: 在您想要處理問題的地方,透過例外處理程序擷取例外狀況。 catch 關鍵字用於捕獲異常。

  • try: try 區塊中的程式碼標識將被啟動的特定例外。它後面通常跟著一個或多個 catch 區塊。

如果有一個區塊拋出一個例外,捕捉例外的方法會使用 trycatch 關鍵字。 try 區塊中放置可能拋出例外狀況的程式碼,try 區塊中的程式碼稱為保護程式碼。使用try/catch 語句的語法如下所示:

try
{
   // 保护代码
}catch( ExceptionName e1 )
{
   // catch 块
}catch( ExceptionName e2 )
{
   // catch 块
}catch( ExceptionName eN )
{
   // catch 块
}

如果try 區塊在不同的情境下會拋出不同的異常,這個時候可以嘗試羅列多個catch 語句,用於捕捉不同類型的異常。

拋出例外

您可以使用 throw 語句在程式碼區塊中的任何地方拋出例外。 throw 語句的操作數可以是任意的表達式,而表達式的結果的型別決定了拋出的例外的型別。

以下是嘗試除以零時拋出例外的實例:

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

捕獲異常

catch 區塊跟在try 區塊後面,用於捕捉異常。您可以指定想要捕捉的異常類型,這是由 catch 關鍵字後的括號內的異常聲明決定的。

try
{
   // 保护代码
}catch( ExceptionName e )
{
  // 处理 ExceptionName 异常的代码
}

上面的程式碼會捕獲一個類型為 ExceptionName 的例外。如果您想要讓catch 區塊能夠處理try 區塊拋出的任何類型的異常,則必須在例外聲明的括號內使用省略號...,如下所示:

try
{
   // 保护代码
}catch(...)
{
  // 能处理任何异常的代码
}

下面是一個實例,拋出一個除以零的異常,並在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;
}

由於我們拋出了一個類型為 const char* 的異常,因此,當捕獲該異常時,我們必須在 catch 區塊中使用 const char*。當上面的程式碼被編譯和執行時,它會產生下列結果:

Division by zero condition!

C++ 標準的異常

C++ 提供了一系列標準的異常,定義在<exception> ; 中,我們可以在程式中使用這些標準的例外。它們是以父子類別層次結構組織起來的,如下所示:

cpp_exceptions.jpg

下表是對上面層次結構中出現的每個例外的說明:

異常描述
#std::exception該異常是所有標準C++ 異常的父類別。
std::bad_alloc該例外可以透過 new 拋出。
std::bad_cast該例外可以透過 dynamic_cast 拋出。
std::bad_exception這在處理 C++ 程式中無法預期的例外狀況時非常有用。
std::bad_typeid該例外可以透過 typeid 拋出。
std::logic_error#理論上可以透過讀取程式碼來偵測到的例外。
std::domain_error當使用了一個無效的數學域時,會拋出該例外。
std::invalid_argument當使用了無效的參數時,會拋出該例外。
std::length_error當創建了太長的 std::string 時,會拋出該例外。
std::out_of_range該異常可以透過方法拋出,例如std::vector 和std::bitset<>::operator[]() 。
std::runtime_error#理論上不可以透過讀取程式碼來偵測到的例外。
std::overflow_error當數學上溢發生時,會拋出該例外。
std::range_error當嘗試儲存超出範圍的值時,會拋出該例外。
std::underflow_error當發生數學下溢時,會拋出該例外。

定義新的例外

您可以透過繼承和重載 exception 類別來定義新的例外。下面的實例示範如何使用std::exception 類別來實作自己的例外:

#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)
  {
    //其他的错误
  }
}

這將產生以下結果:

MyException caught
C++ Exception

在這裡,what()是異常類別提供的一個公共方法,它已被所有子異常類別重載。這將傳回異常產生的原因。

熱AI工具
Undress AI Tool
Undress AI Tool

免費脫衣圖片

AI Clothes Remover
AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undresser.AI Undress
Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

Stock Market GPT
Stock Market GPT

人工智慧支援投資研究,做出更明智的決策

熱門工具
記事本++7.3.1
記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版
SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1
禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6
Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版
SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)