异常处理的几个常见问题

目录

 

异常处理的常见问题

异常处理到底是干什么用的?

异常处理如何使用?

如果异常被抛出,是否还会向下继续执行?

示例代码

运行结果

结果解析

如果异常被抛出,如何处理其所在作用域内的成员变量?

代码示例

运行结果

结果解析

综上所述,异常处理执行流程是什么?

如何传递自定义异常?

如何通过继承进行自定义异常处理?

异常处理程序编写时三个应该与三个不应该


异常处理的常见问题

异常处理到底是干什么用的?

其实异常处理使用try-catch语句以及exception异常处理标志来实现的,try用于捕获异常,catch用来捕获异常并且进行相应的处理。当我们遇到可能发生异常的语句可以用try-catch来实现异常的识别,比如:我们通常以new动态申请内存空间,但是如果申请空间过大计算机内存不过用了怎么办呢?我们要精准识别这种错误可以用try-catch语句来实现,详见“异常处理如何使用?”的例程。

异常处理如何使用?

用于识别特定的异常:

#include <exception>  
#include <iostream>  
using namespace std;  
  
int main()  
{  
    try  // 用于识别try{}语句块中的异常并且抛出异常
    {  
        int Size;  
        cin >> Size;  
        int *ArrayPointer = new int[Size];  // 我输入-1,出现bad_alloc异常
        delete[] ArrayPointer;  
    }  
    catch (bad_alloc& exp)  // 被相应的catch语句捕获
    {  
        cout << exp.what() << endl;  
    }  
    catch (exception& exp)  // 用于捕获除bad_alloc之外的异常
    {  
        cout << exp.what() << endl;  
    }  
} 

 

如果我们识别全部异常,那我们可以简化上述步骤:

#include <exception>  
#include <iostream>  
using namespace std;  
  
int main()  
{  
    try  
    {  
        int Size;  
        cin >> Size;  
        int *ArrayPointer = new int[Size];  
        delete[] ArrayPointer;  
    }  
    catch (exception& exp)  
    {  
        cout << exp.what() << endl;  
    }  
}  

如果异常被抛出,是否还会向下继续执行?

示例代码

#include <exception>  
#include <iostream>  
using namespace std;  
  
int main()  
{  
    try // 用于识别try{}语句块中的所有异常并且抛出异常  
    {  
        int Size;  
        cin >> Size;  
        int *ArrayPointer = new int[Size];  
        cout << "正在继续执行" << endl; // 不会继续向下执行,直接由catch捕获异常然后执行处理程序  
        delete[] ArrayPointer;  
    }  
    catch (bad_alloc& exp) // 用于捕获bad_alloc特定异常  
    {  
        cout << exp.what() << endl;  
    }  
    catch (exception& exp) // 用于捕获除bad_alloc之外的其他所有异常  
    {  
        cout << exp.what() << endl;  
    }  
} 

 

运行结果

 

结果解析

我们在结果中看到当异常抛出直接就会被catch捕捉并且进入catch异常处理程序中进行执行。

如果异常被抛出,如何处理其所在作用域内的成员变量?

代码示例

#include <exception>  
#include <iostream>  
using namespace std;  
  
struct Mumber_A   
{  
    Mumber_A()  
    {  
        cout << "调用构造函数" << endl;  
    }  
    ~Mumber_A()  
    {  
        cout << "调用析构函数" << endl;  
    }  
};  
  
void ExceptionShow()  
{  
    Mumber_A Obj_A;  
    throw "出现异常";  
}  
  
int main()  
{  
    try  
    {  
        ExceptionShow();  
    }  
    catch (const char* Obj)  
    {  
        cout << "异常处理" << endl;  
    }  
    cout << "主程序结束" << endl;  
}  

运行结果

 

结果解析

我们通过运行结果可以看到,当try{}语句块抛出异常后,首先要做的就是析构try{}语句块中的所有对象,然后在跳转至catch中去执行异常处理程序。

从结果来看,当遇到异常被抛出,立刻就会被catch捕获并且进入catch异常处理程序。

综上所述,异常处理执行流程是什么?

 

如何传递自定义异常?

#include <iostream>  
#include <exception>  
using namespace std;  
  
void ExceptionShow1()  
{  
    throw "抛出异常";  
}  
  
void ExceptionShow2()  
{  
    ExceptionShow1();  
    throw; // 继续抛出异常  
}  
  
int main()  
{  
    try  
    {  
        ExceptionShow2 ();  
    }  
    catch (const char* exp)  // 捕捉ExceptionShow2抛出的异常
    {  
        cout << "异常处理程序" << endl;  
    }  
}  

如何通过继承进行自定义异常处理?

#include <iostream>  
#include <exception>  
#include <string>  
using namespace std;  
  
class CustomException : public exception  
{  
private:  
    string reason;  
public:  
    CustomException(string reason)  
    {  
        this->reason = reason;  
    }  
    ~CustomException()  
    {  
        cout << "调用CustomException的析构函数" << endl;  
    }  
    virtual const char* what() const noexcept // throw()与noexcept等价,表明:在这个函数作用域内不可以抛出任何异常  
    {  
        return reason.c_str(); // 重载虚函数时,子类与父类各方面都必须一样  
    }  
};  
double Division(double divisor,double dividend)  
{  
    if (dividend == 0)  
    {  
        throw CustomException("除数为零");  
    }  
    return divisor / dividend;  
}  
  
int main()  
{  
    try  
    {  
        cout << "结果为" << Division(8, 0) << endl;  
    }  
    catch (exception& exp)  // 一定要用引用
    {  
        cout << exp.what() << endl;  
    }  
}  

自定义异常处理最好的办法是对exception进行继承,因为这样可以确保在重用exception所有异常标志的基础上添加自定义的异常标志。

自定义异常处理的优点?

当然,并非必须这样做,但这让您能够重用捕获std::exception异常的所有catch( )块。编写自己的异常类时,可以不继承任何类,但必须在所有相关的地方插入新的catch(MyNewExceptionType&)语句。

异常处理程序编写时三个应该与三个不应该

 

猜你喜欢

转载自blog.csdn.net/weixin_45590473/article/details/108307581