異常是程式在執行期間產生的問題。c++ 異常是指在程式執行時發生的特殊情況,比如嘗試除以零的操作。
異常提供了一種轉移程式控制權的方式。c++ 異常處理涉及到三個關鍵字:try、catch、throw。
如果有乙個塊丟擲乙個異常,捕獲異常的方法會使用try和catch關鍵字。try 塊中放置可能丟擲異常的**,try 塊中的**被稱為保護**。使用 try/catch 語句的語法如下所示:
try
catch( exceptionname e1 )
catch( exceptionname e2 )
catch( exceptionname en )
return (a/b);
}
catch塊跟在try塊後面,用於捕獲異常。您可以指定想要捕捉的異常型別,這是由 catch 關鍵字後的括號內的異常宣告決定的。
try
catch( exceptionname e )
上面的**會捕獲乙個型別為exceptionname的異常。如果您想讓 catch 塊能夠處理 try 塊丟擲的任何型別的異常,則必須在異常宣告的括號內使用省略號 ...,如下所示:
try
catch(...)
下面是乙個例項,丟擲乙個除以零的異常,並在 catch 塊中捕獲該異常。
#include using namespace std;
double division(int a, int b)
return (a/b);}
int main ()
catch (const char* msg)
return 0;
}
由於我們丟擲了乙個型別為const char*的異常,因此,當捕獲該異常時,我們必須在 catch 塊中使用 const char*。當上面的**被編譯和執行時,它會產生下列結果:
division by zero condition!
c++ 提供了一系列標準的異常,定義在中,我們可以在程式中使用這些標準的異常。它們是以父子類層次結構組織起來的,如下所示:
下表是對上面層次結構**現的每個異常的說明:
異常描述
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 #include using namespace std;
struct myexception : public exception};
int main()
catch(myexception& e)
catch(std::exception& e)
}
這將產生以下結果:
myexception caught
c++ exception
在這裡,what()是異常類提供的乙個公共方法,它已被所有子異常類過載。這將返回異常產生的原因。
const throw() 不是函式,這個東西叫異常規格說明,表示 what 函式可以丟擲異常的型別,型別說明放到 ()裡,這裡面沒有型別,就是宣告這個函式不丟擲異常,通常函式不寫後面的就表示函式可以丟擲任何型別的異常。
異常規格說明
1、異常規格說明的目的是為了讓函式使用者知道該函式可能丟擲的異常有哪些。 可以在函式的宣告中列出這個函式可能拋擲的所有異常型別。例如:
void fun() throw(a,b,c,d);
2、若無異常介面宣告,則此函式可以拋擲任何型別的異常。
3、不拋擲任何型別異常的函式宣告如下:
#include #include using namespace std;
class myexception
myexception(const myexception &other) : message_(other.message_)
virtual ~myexception()
const char *what() const
private:
string message_;
};class myexceptiond : public myexception
myexceptiond(const myexceptiond &other)
: myexception(other)
~myexceptiond()
};void fun(int n) throw (int, myexception, myexceptiond)
else if (n == 2)
else if (n == 3)
}void fun2() throw()
int main(void)
catch (int n)
catch (myexceptiond &e)
catch (myexception &e)
return 0;
}
c++ primer 中關於 what()的解釋:在之前的例子裡,我們使用了乙個 throw 表示式以避免把兩個代表不同書籍的 sales_item 相加。我們假設執行 sales_item 物件加法的**是與使用者互動的**分離開的。其中與使用者互動的**負責處理發生的異常,它的形式可能如下所示:
while (cin >> item1 >> item2) catch (runtime_error err)
}
程式本來要執行的任務出現在 try 語句塊中,是因為這段**可能會丟擲乙個 runtime_error 型別的異常。
try 語句塊對應乙個 catch 子句。該子句負責處理類行為 runtime_error 的異常。如果 try 語句塊的**丟擲了runtime_error 異常,接下來執行 catch 塊內的語句。在我們書寫的 catch 子句中,數出一段提示資訊要求使用者指定程式是否繼續。如果使用者輸入 n,執行 break 語句並退出 while 迴圈;否則,直接執行 while 迴圈的右側花括號,意味著程式控制權條回到 while 條件部分準備下一次迭代。
給使用者的提示資訊中輸出了 err.what() 的返回值。我們知道 err 的型別是 runtime_error,因此能推斷 what 是 runtime_error 類的乙個成員函式。每個標準庫異常類都定義了名為 what 的成員函式。這些函式沒有引數,返回值是 c 風格字串(即 const char *)其中,runtime_error 的 what 成員函式返回的是初始化乙個具體物件所用的 string 物件的副本。如果上一節編寫的**丟擲異常,則本節的 catch 子句輸出:
data must refer to same isbn
try again? enter y or n
C 異常處理
結構化異常 structured exception vs c 異常 c exception 大家都知道c 異常是c 語言的乙個特性,使用者可以使用throw的方式來丟擲異常,try catch 來捕獲異常。結構化異常是諸如,zero divided,access violations等異常,這些異...
c 異常處理
一 概述 c 自身有著非常強的糾錯能力,發展到如今,已經建立了比較完善的異常處理機制。c 的異常情況無非兩種,一種是語法錯誤,即程式中出現了錯誤的語句,函式,結構和類,致使編譯程式無法進行。另一種是執行時發生的錯誤,一般與演算法有關。關於語法錯誤,不必多說,寫 時心細一點就可以解決。c 編譯器的報錯...
C 異常處理
程式設計師常常忽視異常處理的重要性,這給他們自己的 造成相當大損害。本文將討論如何在c 中使用異常處理,並介紹在應用 中新增 片段以防止某些錯誤的一些簡單方法,這些錯誤可能導致程式異常終止。結構化異常處理 net框架提供一種標準的錯誤報告機制稱為結構化異常處理。這種機制依賴於應用中報告錯誤的異常。在...