C++ 异常处理机制讲解

异常处理

除数为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,之后我们能够打印我们定义的信息:

执行顺序:

  1. 执行try块的函数,如果正常则什么都不会执行
  2. 如果函数抛出了一个异常,不管是什么类型的,只要你抛出了throw异常,那么catch就会接受这个throw的消息,打印catch中的信息
  3. 注意:函数中抛出了错误,则下面的代码将不会执行,会直接返回,例如,不会执行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;
}

在这里插入图片描述

posted @ 2022-10-02 16:25  hugeYlh  阅读(13)  评论(0编辑  收藏  举报  来源