异常概念
异常是一种处理错误的方式,当一个函数发现自己无法处理的错误时就可以抛出异常,让函数的
直接或间接的调用者处理这个错误。
throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
catch: 在您想要处理问题的地方,通过异常处理程序捕获异常.catch 关键字用于捕获异常,可以有多个catch进行捕获。
try: try 块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个 catch 块。
其实可以简单理解为升级版的if判断。如果执行出错就抛出异常,然后执行解决方案。
举个简单的栗子:
void func_1(int x)
{
if (x == 0)//如果我们的x==0就抛出异常
throw "x==0";//需要一个字符串来接收抛出的异常
cout <<200/x<<endl;
}
int main()
{
try
{
func_1(0);//将会抛出异常的代码放在try语句里面。
}
catch (const char*data)//接收一个字符串的异常
{
cout << data << endl;
}
return 0;
}
其实我们这里可以直接打印错误,然后再返回就行,但是我们可以选择抛出异常。然后终止函数,去执行catch里面语句。这里需要注意的是我们可能要抛出异常的代码是需要放再try里面的。
tip:catch需要严格的去接收对应抛出的异常,比如上面抛出的是一个字符串,它不会被隐式转换成string,所以需要严格对应。
这样就会报错。
异常的重新抛出
有可能单个的catch不能完全处理一个异常,在进行一些校正处理以后,希望再交给更外层的调用
链函数来处理,catch则可以通过重新抛出将异常传递给更上层的函数进行处理。
double Division(int a, int b)
{
// 当b == 0时抛出异常
if (b == 0)
{
throw "Division by zero condition!";
}
return (double)a / (double)b;
}
void Func()
{
// 这里可以看到如果发生除0错误抛出异常,另外下面的array没有得到释放。
// 所以这里捕获异常后并不处理异常,异常还是交给外面处理,这里捕获了再
// 重新抛出去。
int* array = new int[10];
try {
int len, time;
cin >> len >> time;
cout << Division(len, time) << endl;
}
catch (...)
{
cout << "delete []" << array << endl;
delete[] array;
throw;
}
// ...
cout << "delete []" << array << endl;
delete[] array;
}
int main()
{
try
{
Func();
}
catch (const char* errmsg)
{
cout << errmsg << endl;
}
return 0;
}
其实遇到这种情况更好的选择是可以去弄一个智能指针会更好。
自定义异常
实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一个项目中如果大家
随意抛异常,那么外层的调用者基本就没办法玩了,所以实际中都会定义一套继承的规范体系。
这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了。