欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中的throw關鍵字詳解

 更新時間:2023年09月18日 08:42:36   作者:向陽逐夢  
throw關鍵字是在C語言中用來拋出異常的關鍵字,它通常與try和catch一起使用,用于在程序中發(fā)生錯誤時進行異常處理,當遇到無法處理的錯誤情況時,我們可以使用throw關鍵字主動拋出異常,所以本文給大家詳細的介紹一下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;  //對象類型

一個動態(tài)數組的例子

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

下面這段代碼雖然有點長,但它是一個典型的使用異常的場景,請大家耐心閱讀。

    #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;
        }
    }
    //實現(xiàn)動態(tài)數組
    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);  //拋出異常(創(chuàng)建一個匿名對象)
        }
        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();  //拋出異常(創(chuàng)建一個匿名對象)
        }
        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 類實現(xiàn)了動態(tài)數組,它的主要思路是:在創(chuàng)建對象時預先分配出一定長度的內存(通過 malloc() 分配),內存不夠用時就再擴展內存(通過 realloc() 重新分配)。Array 數組只能在尾部一個一個地插入(通過 push() 插入)或刪除(通過 pop() 刪除)元素。我們通過重載過的[ ]運算符來訪問數組元素,如果下標過小或過大,就會拋出異常(第53行代碼);在拋出異常的同時,我們還記錄了當前數組的長度和要訪問的下標。在使用 pop() 刪除數組元素時,如果當前數組為空,也會拋出錯誤。

throw 用作異常規(guī)范

throw 關鍵字除了可以用在函數體中拋出異常,還可以用在函數頭和函數體之間,指明當前函數能夠拋出的異常類型,這稱為異常規(guī)范(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) 虛函數中的異常規(guī)范

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

    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);   //錯!異常規(guī)范不如 throw() 嚴格
        int fun2(int) throw(int);   //對!有相同的異常規(guī)范
        string fun3() throw(string);  //對!異常規(guī)范比 throw(int,string) 更嚴格
    }

2) 異常規(guī)范與函數定義和函數聲明

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

請看下面的幾組函數:

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

請拋棄異常規(guī)范,不要再使用它

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

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

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

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

    #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() 函數中發(fā)生了異常,但是由于 throw 限制了函數只能拋出 char*、exception 類型的異常,所以 try-catch 將捕獲不到異常,只能交給系統(tǒng)處理,終止程序。在 Visual C++ 下,輸出結果為Exception type: int,這說明異常被成功捕獲了。

在 Visual C++ 中使用異常規(guī)范雖然沒有語法錯誤,但是也沒有任何效果,Visual C++ 會直接忽略異常規(guī)范的限制,函數可以拋出任何類型的異常。

以上就是C++中的throw關鍵字詳解的詳細內容,更多關于C++ throw關鍵字的資料請關注腳本之家其它相關文章!

相關文章

  • Python與C++ 遍歷文件夾下的所有圖片實現(xiàn)代碼

    Python與C++ 遍歷文件夾下的所有圖片實現(xiàn)代碼

    這篇文章主要介紹了 Python與C++ 遍歷文件夾下的所有圖片實現(xiàn)代碼的相關資料,需要的朋友可以參考下
    2017-06-06
  • C語言函數超詳細講解上篇

    C語言函數超詳細講解上篇

    函數是一組一起執(zhí)行一個任務的語句。每個?C?程序都至少有一個函數,即主函數?main()?,所有簡單的程序都可以定義其他額外的函數,函數我們分兩篇來講解,接下來開始第一篇
    2022-04-04
  • 12個關于C語言的有趣問答

    12個關于C語言的有趣問答

    這篇文章主要介紹了12個關于C語言的有趣問答,有助于讀者加深對C語言程序設計的理解,需要的朋友可以參考下
    2014-07-07
  • C++實現(xiàn)圖的鄰接矩陣存儲和廣度、深度優(yōu)先遍歷實例分析

    C++實現(xiàn)圖的鄰接矩陣存儲和廣度、深度優(yōu)先遍歷實例分析

    這篇文章主要介紹了C++實現(xiàn)圖的鄰接矩陣存儲和廣度、深度優(yōu)先遍歷,實例分析了C++實現(xiàn)圖的遍歷技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • 淺析C語言中的內存布局

    淺析C語言中的內存布局

    以下是對C語言中的內存布局進行了詳細的分析介紹。需要的朋友可以過來參考下
    2013-08-08
  • 在C語言中getchar的使用方法和讀取規(guī)則講解

    在C語言中getchar的使用方法和讀取規(guī)則講解

    getchar中文意思是獲取字符,getchar函數從標準輸入輸出里讀取下一個字符,返回類型為int整形,返回用戶輸入的ASCII碼值,如果到達文件末尾或者出錯返回EOF,這篇文章主要介紹了在C語言中getchar的使用方法和讀取規(guī)則,需要的朋友可以參考下
    2022-12-12
  • C++11中的智能指針和垃圾回收使用

    C++11中的智能指針和垃圾回收使用

    本文主要介紹了C++11中的智能指針和垃圾回收使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • C++實現(xiàn)小型復數計算器

    C++實現(xiàn)小型復數計算器

    這篇文章主要為大家詳細介紹了C++實現(xiàn)小型復數計算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C/C++實現(xiàn)HTTP協(xié)議解析的示例代碼

    C/C++實現(xiàn)HTTP協(xié)議解析的示例代碼

    基本上,HTTP?是一種基于?TCP/IP?的通信協(xié)議,用于通過?Web?傳遞?HTML?文件、圖像文件、查詢結果等數據。本文將用C/C++實現(xiàn)HTTP協(xié)議解析,感興趣的可以了解一下
    2022-07-07
  • C++結合QT實現(xiàn)帶有優(yōu)先級的計算器功能

    C++結合QT實現(xiàn)帶有優(yōu)先級的計算器功能

    這篇文章主要介紹了C++結合QT實現(xiàn)帶有優(yōu)先級的計算器,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01

最新評論