C++異常處理

要點(diǎn)

  • 異常根據(jù)拋出的類型捕獲,可以直接捕獲接收或通過(guò)引用接收。但二者同時(shí)只能存在一個(gè)。
  • 棧內(nèi)存創(chuàng)建的對(duì)象指針拋出后會(huì)產(chǎn)生野指針問(wèn)題
  • 動(dòng)態(tài)創(chuàng)建對(duì)象的指針拋出后可以正常捕獲使用,但是需要手動(dòng)釋放。
  • 函數(shù)聲明可以加上異常聲明。限制函數(shù)可以拋出的異常類型。
  • 異常有棧解鎖機(jī)制,棧內(nèi)存中創(chuàng)建的對(duì)象在異常拋出后會(huì)自動(dòng)析構(gòu)。
  • 異??梢圆东@并繼續(xù)向上拋出。

示例代碼

#include "stdafx.h"
#include "iostream"
#include "string.h"
using namespace std;
#pragma warning(disable : 4996)  
class ExceptionA {
private:
    char *msg;
public:
    ExceptionA(const char *msg) {
        cout << "構(gòu)造" <<msg<< endl;
        if (msg == NULL) {
            this->msg = NULL;
        }else{
            this->msg = new char[strlen(msg) + 1];
            strcpy(this->msg, msg);
        }
    }
    char * getMsg()const {
        return this->msg;
    }
    ExceptionA(const ExceptionA& e) {
        cout << "拷貝構(gòu)造" << endl;
        if (this->msg == NULL) {
            delete[]this->msg;
        }
        this->msg = new char[strlen(e.getMsg()) + 1];
        strcpy(this->msg, e.getMsg());
    }
    ~ExceptionA() {
        cout << "析構(gòu)" << msg << endl;
        if (this->msg != NULL) {
            delete[]this->msg;
        }
    }
};

void funcA(int x) {

    switch (x)
    {
    case 0:{
        //throw異常后,temp1會(huì)自動(dòng)析構(gòu),而temp不會(huì)自動(dòng)析構(gòu)和釋放
        ExceptionA *temp = new ExceptionA("temp");
        ExceptionA temp1("temp1");
        throw 1;
    }
        break;
    case 1:
        throw 'a';
        break;
    case 2:
        //可以直接接受或使用引用接收。推薦使用引用接收
        throw(ExceptionA("msg 2"));
        break;
    case 3:
        //拋出指針,但對(duì)象會(huì)被清理。catch到的指針是野指針
        throw(&ExceptionA("msg 3"));
        break;
    case 4: {
        //拋出動(dòng)態(tài)分配的指針。catch到后使用完后需要delete
        ExceptionA* e = new ExceptionA("msg4");
        throw(e);
    }
        break;
    case 5:
        throw 3.14f;
    case 6:
        throw 3.14;
    }
    cout << "funcA success " << x << endl;
}

void funcB(int index) throw(float ,double){
    try {
        funcA(index);
    }
    catch (int e) {
        cout << "catch int " << e << endl;
    }
    catch (char e) {
        cout << "catch char " << e << endl;
    }
    catch (ExceptionA e) {
        cout << "catch  ExceptionA " << e.getMsg() << endl;
    }
    //使用對(duì)象接收和使用對(duì)象的引用接收不能同時(shí)存在。
    //catch (ExceptionA &e) {
    //  cout << "catch  ExceptionA & " << e.getMsg() << endl;
    //}
    catch (ExceptionA *e) {
        cout << "catch  ExceptionA * " << e->getMsg() << endl;
        delete e;
    }
    catch (float e) {
        //接續(xù)向上拋出異常
        cout << "catch float and throw  " << e << endl;
        throw e;
    }
    catch (double e) {
        //接續(xù)向上拋出異常,但函數(shù)的方法上有限制可以拋出異常的類型。這里會(huì)出錯(cuò)
        cout << "catch double and throw  " << e << endl;
        throw e;
    }
}
int main()
{
    try {
        funcB(6);
    }
    catch (float e) {
        cout << "main catch " << e << endl;
    }
    return 0;
}

異常處理場(chǎng)景演示

  • funcB(0)


    0.png

    這里創(chuàng)建了兩個(gè)對(duì)象一個(gè)在堆中動(dòng)態(tài)創(chuàng)建temp.一個(gè)在棧中temp1。執(zhí)行結(jié)果看到temp1自動(dòng)被析構(gòu),而temp未被析構(gòu)。c++在異常拋出后有棧解鎖機(jī)制,會(huì)自動(dòng)析構(gòu)在棧中創(chuàng)建的對(duì)象。

  • funcB(1)


    1.png

    這里就是按類型在funcA中正常的catch

  • funcB(2) 棧內(nèi)存對(duì)象

    • 用對(duì)象直接接收


      2.png

      這里看到當(dāng)拋出對(duì)象時(shí)候,catch中接受時(shí)類似方法實(shí)參到形參的傳遞,進(jìn)行拷貝構(gòu)造。

    • 用對(duì)象的引用接收


      7.png

      catch中得到對(duì)象的引用。

  • funcB(3) 拋出棧內(nèi)存對(duì)象的指針


    3

    catch得到對(duì)象的指針前。對(duì)象已被析構(gòu),這里得到的就是野指針。

  • funcB(4) 動(dòng)態(tài)創(chuàng)建對(duì)象


    4.png

    可以正常catch到并使用。但使用完后需要手動(dòng)釋放。

  • funcB(5) 捕獲到異常后繼續(xù)向上拋出


    5.png

    funcA中繼續(xù)拋出,在main中正常捕獲。

  • funcB(6) 方法異常類型聲明


    6.png

    限制方法能夠拋出異常的類型,如果不在范圍內(nèi),運(yùn)行會(huì)報(bào)錯(cuò)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容