前言
throw
关键字仅可用于C++。
关于异常
异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。
在C语言中,如果程序的运行出现异常、错误,我们想提供方案处理这些异常时,我们面临许多问题,如:
- c语言没有提供统一(标准)的方式来处理错误;
- 无法保证错误会被正确的处理;
- 错误的传播无法控制,特别是在函数的嵌套调用时;
而C++提供了处理异常的关键字:throw
、try
、catch
。
抛出异常
你可以使用throw
抛出一个异常:
throw err;
如:
throw"Division by 0!";
throw 0x12345fff;
捕获异常
使用try
和catch
捕获异常:
try{
...//保护代码
}catch(Ex e1){
...//异常处理
}catch(Ex e2){
...//异常处理
}catch(Ex eN){
...//异常处理
}
try
块后面通常跟着1个或多个catch
块,用于捕获保护代码里可能抛出的异常。
当保护代码抛出异常后,程序将跳出try
块(即使在另一个函数域中),并在catch
块中寻找关于该异常的处理办法,Ex e
中Ex即抛出异常的类型,e即处理异常中对异常的称呼(类似函数的参数)
实例
#include<iostream>
using namespace std;
template<class t>
t divide(t a,t b){
if(b==0) throw"Devided by zero!";
return a/b;
}
int main(){
try{
cout<<divide(10,5)<<endl
<<divide(10,0)<<endl
<<divide(18,2)<<endl;
}
catch(const char* err){
cerr<<err<<endl;//std::cerr标准错误流异常输出
}
return 0;
}
2
Devided by zero!
不难看出,当try
块中抛出异常后,程序将第一时间退出保护代码,后面的语句不会被执行。
标准异常
C++提供了一系列标准异常,在<exception>
中,实质是一堆相互继承的父子关系类,关系如图:(std
后要加俩:
)
重载异常
你可以通过重载继承exception
父异常类来创建自己的异常:
#include<iostream>
#include<exception>
using namespace std;
class myexception
: public exception
{
public:
const char* what() const throw() {
return "Exception : Myexception\n";
}
};
int main() {
try {
throw myexception();
}
catch (myexception mye) {
cout << "Exception caught!\n"
<< mye.what();
}
return 0;
}
Exception caught!
Exception : Myexception
一行一行看,
首先:
class myexception : public exception { public:...
表示public
继承标准库异常类,定义类myexception
。
const char * what() const throw()
这一句是关键,what()
是异常类提供的公共方法,且被所有子异常类重载:
//<exception>
class exception{...
public:...
... virtual const char * what() const {...}
}
可以看到,在标准父异常类中,what()
被定义为虚函数,因此你才能随意重载它。what()
函数的标准是没有参数且返回值为C语言风字符串(即const char *
)
从左往右看:
const char *
: 返回类型是字符串。what
: 函数名。()
: 参数列表,均为空。const
: 声明函数无法改变变量。throw()
: 异常规格说明,表示函数无法抛出任何异常。
看到main()
,在try
块里抛出了一个myexception()
:
...
throw myexception();
...
相当于调用了myexception类的默认构造函数(没有定义构造函数,系统会自己创建一个),即创建了一个myexception对象并抛出。可以在myexception
类中定义构造函数:
class myexception{
public:
...
myexception(){cout<<"build func used!\n";}
};
...
则输出会为:
build func used!
Exception caught!
Exception : Myexception
因此在catch()
块中捕捉了这个myexception对象并调用what()
方法。
异常规格说明符
@HaohaoCppDebuger|寻兰
2021/12/20
THANK YOU !