目录
异常处理的常见问题
异常处理到底是干什么用的?
其实异常处理使用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&)语句。
异常处理程序编写时三个应该与三个不应该