C++定义了一个异常类exception类,它有一个名为what()的虚成员函数,会返回一个字符串,该字符串的特征值随实现而异。它在头文件exception中,在代码中我们可以把这个异常类用作其他异常类的基类,也可以使用exception异常。
实例代码:
#include<iostream>
#include<exception>
using namespace std;
class arg_error :public exception
{
public:
arg_error()
:exception("第二个参数错误 不能为0", 1)
{}
};
int add(int a, int b)
{
if (b == 0)
{
arg_error arg;
throw arg;
}
return a / b;
}
int main(void)
{
int a, b, res;
cout << "请输入要除的两个数" << endl;
cin >> a >> b;
try{
res = add(a, b);
cout << res<< endl;
}
catch (exception & p)
{
cout << p.what();
}
return 0;
}
这里我们要注意了,基类exception中的虚函数what()在派生类中重写时,我们所需要打印的异常信息是在构造函数中添加的,并不需要在what()函数中更改什么,为什么这样是由exception类的实现方式决定,可以去查看类的定义。what()函数在类库中的实现如下:
_EXCEPTION_INLINE const char * __CLR_OR_THIS_CALL exception::what() const
{
return _Mywhat ? _Mywhat : "Unknown exception";
}
可见我们需要的是对_Mywhat指针进行赋值的函数 既exception的构造函数:
_EXCEPTION_INLINE __CLR_OR_THIS_CALL exception::exception(const char * const & _What, int)
: _Mywhat(_What), _Mydofree(false) { }
使用方法可以参考实例代码。
上面是我们自己实现的一个类,但C++库中已经为我们实现了很多的异常类。在头文件stdexcept定义了其他几个异常类,首先定义了logic_error和runtime_error,它们都是从exception类继承而来的,这两个类同时又作为基类派生出了同类型具体异常的类供我们使用。
对于使用new导致的内存分配问题,C++的最新处理方式是让new引发bad_alloc异常,在头文件new 中定义,同样也是从exception中继承而来的。