[C++]异常机制

异常的优点

  1. 函数的返回值可以忽略,但异常不可以,从而有助于我们捕获错误
  2. 整形返回值没有任何语义信息,不容易判断错误类型。而异常却包含语义信息,容易找出错误
  3. 整形返回值缺乏上下文信息,异常作为一个类,可以拥有自己的成员,这些成员可以传递足够的信息
  4. 异常处理可以在调用跳级

#include<iostream>
using namespace std;
//异常基本语法
int divide(int a, int b) {
	if (b == 0) {
		throw b;  //抛出异常
	}
	return a / b;
}


void text1() {
	//try语句尝试去捕获异常
	//如果过try捕获到异常catch代码块中内容就会运行
	try {
		divide(10,0);
	}
	//捕获异常并处理
	catch (int) {  //异常会根据类型进行匹配,这里的异常类型就是整型
		cout << "除数为0!" << endl;
	}
}
void text2() {
	try {
		divide(10, 0);
	}
	//捕获异常并处理
	//catch(...)表示捕获所有异常
	catch (int e) {  //可以直接捕获到错误的值
		cout << "除数为0!" << "e的值为:" << e << endl;
	}
}
/*
可以看到在CallDivide()函数中并没有异常处理机制
但是运行环境,错误还是被捕获了
因为C++的异常处理机制是跨函数的
当一个异常被抛出,就会逐层向上传递,直到被处理机制处理
如果最后也没有处理异常,程序就会挂机,无法正常运行
这也说明了C++的异常是必须处理的
*/
void CallDivide(int a,int b) {
	divide(a, b);
}
void text3() {
	try {
		CallDivide(10, 0);
	}catch(int e){
		cout << "除数为0!" << "e的值为:" << e << endl;
	}
}


int main() {
	text1();
	text3();
	return 0;
}

栈解旋(unwinding)

在捕获异常后,try语句块内的代码定义的局部变量,都会自动调用析构函数被析构

#include<iostream>
using namespace std;


class Person {
public:
	Person() {
		cout << "对象构建!" << endl;
	}
	~Person() {
		cout << "对象析构!" << endl;
	}

};
int divide(int a, int b) {
	Person p1, p2;
	if (b == 0) {
		throw b;  //抛出异常
	}
	return a / b;
}
void text() {
	try {
		divide(10, 0);
	}
	//捕获异常并处理
	catch (int e) {  //可以直接捕获到错误的值
		cout << "异常捕获"<< endl;
	}
}
int main(){
    text();
    return 0;
}

#####运行结果

对象构建!
对象构建!
对象析构!
对象析构!
异常捕获

异常接口声明

为了加强程序的可读性,可以函数声明中列出可能抛出异常的所有类型。例如:

void func() throw(int,float,char){}
//表示该函数只能抛出以上三种类型的异常
void func() throw(){}
//表示不能抛出任何异常
void func(){}
//可以抛出所有异常

异常类型

throw的异常时有类型的,可以是数字,字符串,类对象,catch需严格匹配异常类型

普通类型元素,调用拷贝构造异常对象catch处理完后就析构

引用类型对象,不会调用拷贝构造,异常处理完就析构

利用指针对象,不能使用栈内存构造对象,需要使用堆内存(new)创建对象,防止对象先析构,再处理异常

发布了18 篇原创文章 · 获赞 2 · 访问量 239

猜你喜欢

转载自blog.csdn.net/renboyu010214/article/details/104416803