1. 程式人生 > 實用技巧 >C++學習筆記之 異常

C++學習筆記之 異常

異常

目錄

基本概念

異常處理就是處理程式中的錯誤

語法

#include <iostream>

using namespace std;

int myDivision(int a,int b) {
    if (b == 0) {
        // return -1;

        // 丟擲異常
        throw -1;
    } else if (b < 0) {
        throw 3.14;
    }
    return a / b;
}

int main() {
    try {
        int ret = myDivision(10,-10);
        ret = myDivision(10,0);
    } catch (int a) {
        cout << "捕獲int異常" << a << endl;
    } catch (...) {
        cout << "捕獲其他異常" << endl;
    }

    return 0;
}
捕獲其他異常

捕獲自定義異常

#include <iostream>

using namespace std;

class MyException
{
public:
    void printERROR() {
        cout << "我自己的異常" << endl;
    }
};

int myDivision(int a,int b) {
    if (b == 0) {
        // return -1;

        // 丟擲異常
        throw MyException();
    }
    return a / b;
}

int main() {
    try {
        int ret = myDivision(10,-10);
        ret = myDivision(10,0);
    } catch (MyException e) {
        e.printERROR();
    }

    return 0;
}
我自己的異常

異常的介面宣告

只允許函式在執行中丟擲某種型別的異常

#include <iostream>

using namespace std;

class MyException
{
public:
    void printERROR() {
        cout << "我自己的異常" << endl;
    }
};

// 只允許丟擲int,MyException異常
int myDivision(int a,int b)throw(int,MyException) // C++14不允許,C++11不贊成
{
    if (b == 0) {
        // return -1;

        // 丟擲異常
        throw MyException();
    }
    return a / b;
}

int main() {
    try {
        int ret = myDivision(10,-10);
        ret = myDivision(10,0);
    } catch (MyException e) {
        e.printERROR();
    }

    return 0;
}

棧解旋

當發生異常時,從進入try塊後,到異常被拋擲前,這期間在棧上的構造的所有物件都會被自動析構。析構的順序與構造的順序相反,這一過程被稱為棧的解旋

異常變數的生命週期

// throw MyException();   MyException e  呼叫拷貝建構函式,建立新的異常物件
// throw MyException();   MyException& e  不呼叫拷貝構造,推薦使用
// throw &MyException();   MyException* e  物件被提前釋放,如果操作e,非法操作
// throw new MyException();   MyException* e 要管理釋放 delete e

異常的多型使用

父類:BaseException 虛擬函式:printERROR

演示

#include <iostream>

using namespace std;

class BaseException // 異常父類
{
public:
    virtual void printERROR() {
        ;
    }
};

class NULLPointerException : public BaseException // 空指標異常
{
public:
    void printERROR() {
        cout << "NULLPointerException" << endl;
    }
};

void doTry() {
    throw NULLPointerException();
}

int main() {
    try {
        doTry();
    } catch (NULLPointerException &e) {
        e.printERROR();
    }

    return 0;
}
NULLPointerException

標準異常

https://blog.csdn.net/weixin_42078760/article/details/80646206

#include <iostream>
#include <stdexcept>

using namespace std;

void doTry() {
    throw out_of_range("資料越界");
}

int main() {
    try {
        doTry();
    } catch (exception &e) {
        cout << e.what() << endl;
    }

    return 0;
}
資料越界