C++ 异常处理机制讲解
原创
©著作权归作者所有:来自51CTO博客作者小萝卜爱吃兔子的原创作品,请联系作者获取转载授权,否则将追究法律责任
文章目录
- 除数为0
- 内存分配异常
- 异常传递过程
- 处理自定义异常:
异常处理
除数为0
我们通过一个简单的例子来引入
例如:
int divide1(int v1, int v2) throw(int) {
return v1 / v2;
}
我们有一个简单的除法函数,计算所得的结果是多少,我们可以传递两个参数,但是你有没有想过,如果我们传递被除数一个零会出现什么?
我们的程序会直接崩毁。但是我们无法得到提示,也就是说,我们无法知道我们是否写的没错。
我们可以在函数内部加一个throw的东西,指的是抛出一个引用,这个东西可以是任意类型:
int divide1(int v1, int v2) throw(int) {
if (v2 == 0) {
// 抛出异常
throw 666;
}
return v1 / v2;
}
这样我们就定义了一个简单的异常处理函数,那么我们在主函数应该如何接受这个异常呢?
int main() {
try{
divide1(10, 0);
}
catch (int error){
cout << "除数不能为0! " << error << endl;
}
getchar();
return 0;
}
注意:因为我们的ethrow抛出了一个int值,所以我们想要捕获这异常,就要传递一个int,之后我们能够打印我们定义的信息:
执行顺序:
- 执行try块的函数,如果正常则什么都不会执行
- 如果函数抛出了一个异常,不管是什么类型的,只要你抛出了throw异常,那么catch就会接受这个throw的消息,打印catch中的信息
- 注意:函数中抛出了错误,则下面的代码将不会执行,会直接返回,例如,不会执行return,直接被catch接受了。
执行结果: 注意:throw的数值不重要,重要的是告诉catch,你要接收这个异常,你可以throw任意类型。const char* int double 等等等,打不打印此throw由你决定,重要的是捕获此异常。
内存分配异常
使用异常处理来处理我们的内存分配失败的情况:
for (int i = 0; i < 99999; i++) {
try {
int *p = new int[9999999];
} catch (const exception &exception) {
cout << "产生异常了:内存不够用 - " << exception.what() << endl;
break;
}
}
我们会直接catch抛出异常,此catch的内容指的是接受所有的任意类型,也可以使用三个点 …
异常传递过程
void func1() {
cout << "func1-begin" << endl;
throw 666;
cout << "func1-end" << endl;
}
void func2() {
cout << "func2-begin" << endl;
func1();
cout << "func2-end" << endl;
}
void test3() {
cout << "test3-begin" << endl;
try {
func2();
} catch (int exception) {
cout << "产生异常了(int):" << exception << endl;
}
cout << "test3-end" << endl;
}
int main()
{
cout<<"main-begin"<<endl;
text3()
cout<<"main-end"<<endl;
return 0;
}
解析:我们通过main函数调用一个test3函数,test3函数又调用func2函数,func2函数又调用了func1,我们假定func1抛出了一个异常,则程序的执行情况会是怎样的??
注意:我们的try catch在test3函数中处理异常。
我们来分析一下:
main函数进入test3函数,进入func2函数,进入func1函数,然后抛出异常,注意,没有catch捕获的话,下面的语句将不会执行,则一直到test3捕获完毕后,才会打印end。
处理自定义异常:
标准库自带的标准错误:
我们定义的和标准库的其实是一样的:
// 所有异常的基类
class Exception {
public:
virtual const char *what() const = 0;
virtual int code() const = 0;
};
class DivideException : public Exception {
public:
const char *what() const {
return "不能除以0";
}
int code() const {
return 202;
}
};
class AddException : public Exception {
public:
const char *what() const {
return "加法有问题";
}
int code() const {
return 201;
}
};
我们通过一个纯虚函数作为错误的基类,不同的类继承自纯虚函数,然后重写其纯虚函数的方法,这样我们就能以不同的捕获来处理不同的错误。。
int divide1(int v1, int v2) throw(int) {
if (v2 == 0) {
// 抛出异常
throw 666;
}
return v1 / v2;
}
int main()
{
try{
divide1(10, 0);
}
catch (const Exception& error){
cout << error.code() << error.what() << endl;
}
return 0;
}