日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ throw

發布時間:2025/3/12 c/c++ 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ throw 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們知道C++ 異常處理的流程,具體為:

拋出(Throw)--> 檢測(Try) --> 捕獲(Catch)

異常必須顯式地拋出,才能被檢測和捕獲到;如果沒有顯式的拋出,即使有異常也檢測不到。

在 C++ 中,我們使用 throw 關鍵字來顯式地拋出異常,它的用法為:

throw exceptionData;

exceptionData 是“異常數據”的意思,它可以包含任意的信息,完全有程序員決定。exceptionData 可以是 int、float、bool 等基本類型,也可以是指針、數組、字符串、結構體、類等聚合類型,請看下面的例子:

char str[] = "http://c.biancheng.net"; char *pstr = str;class Base{}; Base obj;throw 100; //int 類型 throw str; //數組類型 throw pstr; //指針類型 throw obj; //對象類型

一個動態數組的例子

C/C++ 規定,數組一旦定義后,它的長度就不能改變了;換句話說,數組容量不能動態地增大或者減小。這樣的數組稱為靜態數組(Static array)。靜態數組有時候會給編碼代碼不便,我們可以通過自定義的 Array 類來實現動態數組(Dynamic array)。所謂動態數組,是指數組容量能夠在使用的過程中隨時增大或減小。

使用異常示例。

#include <iostream> #include <cstdlib> using namespace std;//自定義的異常類型 class OutOfRange{ public:OutOfRange(): m_flag(1){ };OutOfRange(int len, int index): m_len(len), m_index(index), m_flag(2){ } public:void what() const; //獲取具體的錯誤信息 private:int m_flag; //不同的flag表示不同的錯誤int m_len; //當前數組的長度int m_index; //當前使用的數組下標 };void OutOfRange::what() const {if(m_flag == 1){cout<<"Error: empty array, no elements to pop."<<endl;}else if(m_flag == 2){cout<<"Error: out of range( array length "<<m_len<<", access index "<<m_index<<" )"<<endl;}else{cout<<"Unknown exception."<<endl;} }//實現動態數組 class Array{ public:Array();~Array(){ free(m_p); }; public:int operator[](int i) const; //獲取數組元素int push(int ele); //在末尾插入數組元素int pop(); //在末尾刪除數組元素int length() const{ return m_len; }; //獲取數組長度 private:int m_len; //數組長度int m_capacity; //當前的內存能容納多少個元素int *m_p; //內存指針 private:static const int m_stepSize = 50; //每次擴容的步長 };Array::Array(){m_p = (int*)malloc( sizeof(int) * m_stepSize );m_capacity = m_stepSize;m_len = 0; } int Array::operator[](int index) const {if( index<0 || index>=m_len ){ //判斷是否越界throw OutOfRange(m_len, index); //拋出異常(創建一個匿名對象)}return *(m_p + index); } int Array::push(int ele){if(m_len >= m_capacity){ //如果容量不足就擴容m_capacity += m_stepSize;m_p = (int*)realloc( m_p, sizeof(int) * m_capacity ); //擴容}*(m_p + m_len) = ele;m_len++;return m_len-1; } int Array::pop(){if(m_len == 0){throw OutOfRange(); //拋出異常(創建一個匿名對象)}m_len--;return *(m_p + m_len); }//打印數組元素 void printArray(Array &arr){int len = arr.length();//判斷數組是否為空if(len == 0){cout<<"Empty array! No elements to print."<<endl;return;}for(int i=0; i<len; i++){if(i == len-1){cout<<arr[i]<<endl;}else{cout<<arr[i]<<", ";}} }int main(){Array nums;//向數組中添加十個元素for(int i=0; i<10; i++){nums.push(i);}printArray(nums);//嘗試訪問第20個元素try{cout<<nums[20]<<endl;}catch(OutOfRange &e){e.what();}//嘗試彈出20個元素try{for(int i=0; i<20; i++){nums.pop();}}catch(OutOfRange &e){e.what();}printArray(nums);return 0; }

運行結果:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Error: out of range( array length 10, access index 20 ) Error: empty array, no elements to pop. Empty array! No elements to print.

Array 類實現了動態數組,它的主要思路是:在創建對象時預先分配出一定長度的內存(通過 malloc() 分配),內存不夠用時就再擴展內存(通過 realloc() 重新分配)。Array 數組只能在尾部一個一個地插入(通過 push() 插入)或刪除(通過 pop() 刪除)元素。

我們通過重載過的[ ]運算符來訪問數組元素,如果下標過小或過大,就會拋出異常(第53行代碼);在拋出異常的同時,我們還記錄了當前數組的長度和要訪問的下標。

在使用 pop() 刪除數組元素時,如果當前數組為空,也會拋出錯誤。

throw 用作異常規范

throw 關鍵字除了可以用在函數體中拋出異常,還可以用在函數頭和函數體之間,指明當前函數能夠拋出的異常類型,這稱為異常規范(Exception specification)。

double func (char param) throw (int);

這條語句聲明了一個名為 func 的函數,它的返回值類型為 double,有一個 char 類型的參數,并且只能拋出 int 類型的異常。如果拋出其他類型的異常,try 將無法捕獲,只能終止程序。

如果函數會拋出多種類型的異常,那么可以用逗號隔開:

double func (char param) throw (int, char, exception);

如果函數不會拋出任何異常,那么( )中什么也不寫:

double func (char param) throw ();

如此,func() 函數就不能拋出任何類型的異常了,即使拋出了,try 也檢測不到。

1 虛函數中的異常規范
C++ 規定,派生類虛函數的異常規范必須與基類虛函數的異常規范一樣嚴格,或者更嚴格。只有這樣,當通過基類指針(或者引用)調用派生類虛函數時,才能保證不違背基類成員函數的異常規范。請看下面的例子:

class Base{ public:virtual int fun1(int) throw();virtual int fun2(int) throw(int);virtual string fun3() throw(int, string); }; class Derived:public Base{ public:int fun1(int) throw(int); //錯!異常規范不如 throw() 嚴格int fun2(int) throw(int); //對!有相同的異常規范string fun3() throw(string); //對!異常規范比 throw(int,string) 更嚴格 }

2 異常規范與函數定義和函數聲明
C++ 規定,異常規范在函數聲明和函數定義中必須同時指明,并且要嚴格保持一致,不能更加嚴格或者更加寬松。

請看下面的幾組函數:

//錯!定義中有異常規范,聲明中沒有 void func1(); void func1() throw(int) { }//錯!定義和聲明中的異常規范不一致 void func2() throw(int); void func2() throw(int, bool) { }//對!定義和聲明中的異常規范嚴格一致 void func3() throw(float, char*); void func3() throw(float, char*) { }

拋棄異常規范

異常規范的初衷是好的,它希望讓程序員看到函數的定義或聲明后,立馬就知道該函數會拋出什么類型的異常,這樣程序員就可以使用 try-catch 來捕獲了。如果沒有異常規范,程序員必須閱讀函數源碼才能知道函數會拋出什么異常。

不過這有時候也不容易做到。例如,func_outer() 函數可能不會引發異常,但它調用了另外一個函數 func_inner(),這個函數可能會引發異常。再如,您編寫的函數調用了老式的庫函數,此時不會引發異常,但是庫更新以后這個函數卻引發了異常。總之,異常規范的初衷實現起來有點困難,所以大家達成的一致意見是,最好不要使用異常規范。

異常規范是 C++98 新增的一項功能,但是后來的 C++11 已經將它拋棄了,不再建議使用。

另外,各個編譯器對異常規范的支持也不一樣,請看下面的代碼:

#include <iostream> #include <string> #include <exception> using namespace std;void func()throw(char*, exception){throw 100;cout<<"[1]This statement will not be executed."<<endl; }int main(){try{func();}catch(int){cout<<"Exception type: int"<<endl;}return 0; }

在 GCC 下,這段代碼運行到第 7 行時程序會崩潰。雖然 func() 函數中發生了異常,但是由于 throw 限制了函數只能拋出 char*、exception 類型的異常,所以 try-catch 將捕獲不到異常,只能交給系統處理,終止程序。

在 Visual C++ 下,輸出結果為Exception type: int,這說明異常被成功捕獲了。在 Visual C++ 中使用異常規范雖然沒有語法錯誤,但是也沒有任何效果,Visual C++ 會直接忽略異常規范的限制,函數可以拋出任何類型的異常。

總結

以上是生活随笔為你收集整理的C++ throw的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。