C++中异常处理机制

一、异常处理的基本语法

C++中的异常处理机制中主要的语句为throw、try、catch。其中throw用于在可能出现异常的地方对可能出现异常的变量进行抛出(并且是满足抛出条件时抛出)、try和catch是用于对抛出的变量进行检测和异常处理。在catch中catch()括号内是根据抛出值的数据类型进行匹配的,可以在括号内表明数据类型进行匹配然后在catch语句中抛出错误提示信息,也可以在括号内传入参数,从而获取抛出值的数值

int divide(int x, int y)
{
    if (y == 0)
    {
        throw y;//在可能出现异常的地方对可能出现异常的变量进行抛出(满足抛出条件时)
    }
    else
    {
        return x / y;
    }
}
void test01()
{
    try//try/catch是对抛出的变量进行检测和异常处理
    {
        divide(1,0);
    }
    //catch (int)//获取异常的时候是根据数据类型进行匹配
    //{
    //    cout << "出错了" << endl;
    //}
    catch (int exception)//传入参数,对异常值进行输出
    {
        cout << "出错了" << exception << endl;
    }
}

int main()
{
    test01();
    return 0;
}

 

二、函数中异常的传递机制

假设我们有三个函数,在函数的最底层我们抛出一个待检测和处理的异常,如果异常没有被处理,这个异常会被抛出到第二层的函数体,如果异常还没有被处理,会被抛到第一层的函数中直到被处理为止,如果异常一直没有被处理测程序终止

int divide(int x, int y)//最底层的函数体内抛出异常
{
    if (y == 0)
    {
        throw y;
    }
    else
    {
        return x / y;
    }
}
void test01()//倒数第二层函数体
{
    divide(1, 0);
}

void test02()//最上面的一层函数体
{
    test01();
}

int main()
{
    try
    {
        test02();
    }
    catch (int exception)
    {
        cout << "出错了" << exception << endl;
    }
    return 0;
}

 

三、栈解旋

异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上构造的所有对象都会被自动析构。析构顺序与构造顺序相反,这一过程称为栈的解旋。通俗来说就是在抛出异常的前一刻,所有在try块中申请的栈中的空间都被释放,例如局部变量,对象等等

class Cal
{
public:
    Cal()
    {
        cout << "调用构造函数" << endl;
    }
    ~Cal()
    {
        cout << "调用析构函数" << endl;
    }
};
int divide(int x, int y)
{
    Cal p1;
    if (y == 0)
    {
        throw y;
    }
    else
    {
        return x / y;
    }
}
int main()
{
    try
    {
        divide(1,0);
    }
    catch (int exception)
    {
        cout << "出错了" << exception << endl;
    }
    return 0;
}

 

 

四、异常接口申明

为了加强程序的可读性,可以在函数申明中列出可能抛出异常的所有类型,如果在函数中抛出不符合条件的其他类型这就会报错。

 

 

 

 

int divide(int x, int y) throw(int,char,long,double)//申明可抛出的异常类型
{
    if (y == 0)
    {
        throw y;
    }
    else
    {
        return x / y;
    }
}
int main()
{
    try
    {
        divide(1,0);
    }
    //catch的多重复写
    catch (int exception)
    {
        cout << "出错了" << exception << endl;
    }
    catch (char exception)
    {
        cout << "出错了" << exception << endl;
    }
    catch (long exception)
    {
        cout << "出错了" << exception << endl;
    }
    //catch异常的同一处理
    catch (...)
    {
        cout << "出错了" << endl;
    }
    return 0;
}

 

class Myclass
{
public:
    Myclass(int str)
    {
        this->error = str;
    }
    ~Myclass()
    {
    }
    void output()
    {
        cout << error << endl;
    }
    int error;
};
void test()
{
    //char* str = "abcd";//在VS2017之前字符数组可以这样初始化,但是在VS2017之后,需要先定义一个字符数组,在创建一个字符指针指向数组
    throw Myclass(2);
};
int main()
{
    try 
    {
        test();
    }
    catch (Myclass a)
    {
        a.output();
    }
    return 0;
}

 

 

五、类作为抛出的异常类型

在异常处理机制中catch()严格按照throw()的异常类型进行匹配,因此异常处理不仅仅是对于基础数据类型适用,也适用于类

 

posted @ 2021-11-03 17:45  小康规划  阅读(497)  评论(0)    收藏  举报