C++——C++异常处理

1.C++内置了异常处理的语法元素 try...catch...

try语句处理正常代码逻辑

catch语句处理异常情况

try语句的异常由对应的catch语句处理

C++通过throw语句抛出异常信息

2.C++异常处理分析

throw抛出的异常必须被catch处理

(1)当前函数能够处理异常,程序继续向下执行

(2)当前函数无法处理异常,则函数停止执行并返回

复制代码
#include<iostream>
#include<string>
using namespace std;

double divide(double a, double b) {
	const double delta = 0.0000000000001;
	double ret = 0;
	if (!((-delta < b) && (b < delta))) {
		ret = a / b;
	}
	else {
		throw 0;
	}
	return ret;
}
int main() {
	try {
		double r = divide(1, 1);
		cout << "r=" << r << endl;
	}
	catch (...) {
		cout << "除数为0" << endl;
	}
	return 0;
}

3.同一个try语句可以跟上多个catch语句

(1)catch语句可以定义具体处理的异常类型

(2)不同类型的异常由不同的catch语句负责处理,类型必须严格匹配,不进行任何的类型转换

(3)try语句中可以抛出任何类型的异常

(4)catch(...)用于处理所有类型的异常

(5)任何异常都只能被捕获(catch)一次

复制代码
#include<iostream>
#include<string>
using namespace std;

void demo1() {
	try {
		throw 1;
	}
	catch (char c) {
		cout << "catch (char c)" << endl;
	}
	catch (short c) {
		cout << "catch (short c)" << endl;
	}
	catch (double c) {
		cout << "catch (double c)" << endl;
	}
	catch (int c) {
		cout << "catch (int c)" << endl;
	}
	catch (...) { //只能放在最后

	}
}

int main() {
	demo1(); //catch (int c)
	return 0;
}

4.catch语句块中可以抛出异常

复制代码
#include<iostream>
#include<string>
using namespace std;

int main() {
	try {
		throw 0;
	}
	catch (int i) {
		// 专门捕获 int 类型的异常,并将抛出的异常值赋值给变量 i。
		//程序在执行 throw i 时,会直接跳出当前 catch 块,不会回头执行同一个 try 后的其他 catch;
		throw i; //i=0,执行 throw i,再次抛出 int 类型异常(值为 0),但没人处理
	}
	catch (...) {
		throw;
	}
	return 0;
}

运行结果:

复制代码
#include<iostream>
#include<string>
using namespace std;
int main() {
	try {
		try {
				throw 0;
			}
			catch (int i) {
				cout << "in:catch (int i)" << endl;
				// 专门捕获 int 类型的异常,并将抛出的异常值赋值给变量 i。
				//程序在执行 throw i 时,会直接跳出当前 catch 块,不会回头执行同一个 try 后的其他 catch;
				throw i; //i=0,执行 throw i,再次抛出 int 类型异常(值为 0),但没人处理
			}
			catch (...) {
				cout << "in:catch (...) " << endl;
				throw;
			}
	}
	catch (...) {
		cout << "out:catch (...) " << endl;
	}
	return 0;
}

运行结果:

in:catch (int i)

out:catch (...)

示例:

复制代码
#include<iostream>
#include<string>
using namespace std;
void func(int i) {
	if (i < 0) {
		throw - 1;
	}
	if (i > 100) {
		throw - 2;
	}
	if (i == 11) {
		throw - 3;
	}
	cout << "Run func..." << endl;
}
void Myfunc(int i) {
	try {
		func(i);
	}
	catch (int i) {
		switch (i) {
		case -1:
			throw "1";
			break;
		case -2:
			throw "2";
			break;
		case -3:
			throw "3";
			break;
		}
	}
}
int main() {
	try {
		Myfunc(11);
	}
	catch (const char* cs) {
		cout << cs << endl;
	}
	return 0;
}

运行结果:3

5.异常的类型可以是自定义类型

(1)对于类类型异常的匹配依旧是自上而下严格匹配

(2)一般匹配子类异常的catch放在上部;匹配父类异常的catch放在下部

复制代码
#include<iostream>
#include<string>
using namespace std;
class Base {

};
class Exception :public Base {
	int m_id; //异常id
	string m_desc; //异常的描述信息
public:
	Exception(int id, string desc) {
		m_id = id;
		m_desc = desc;
	}
	int id()const {
		return m_id;
	}
	string description()const {
		return m_desc;
	}
};
void func(int i) {
	if (i < 0) {
		throw - 1;
	}
	if (i > 100) {
		throw - 2;
	}
	if (i == 11) {
		throw - 3;
	}
	cout << "Run func..." << endl;
}
void Myfunc(int i) {
	try {
		func(i);
	}
	catch (int i) {
		switch (i) {
		case -1:
			throw Exception(-1,"1");
			break;
		case -2:
			throw Exception(-2, "2");
			break;
		case -3:
			throw Exception(-3, "3");
			break;
		}
	}
}
int main() {
	try {
		Myfunc(11);
	}
	catch (const Exception& e) {
		cout << e.id() << endl;
		cout << e.description() << endl;
	}
	return 0;
}

运行结果:

-3

3

若在子类的catch分支前加上父类的catch分支:

复制代码
#include<iostream>
#include<string>
using namespace std;
class Base {

};
class Exception :public Base {
	int m_id; //异常id
	string m_desc; //异常的描述信息
public:
	Exception(int id, string desc) {
		m_id = id;
		m_desc = desc;
	}
	int id()const {
		return m_id;
	}
	string description()const {
		return m_desc;
	}
};
void func(int i) {
	if (i < 0) {
		throw - 1;
	}
	if (i > 100) {
		throw - 2;
	}
	if (i == 11) {
		throw - 3;
	}
	cout << "Run func..." << endl;
}
void Myfunc(int i) {
	try {
		func(i);
	}
	catch (int i) {
		switch (i) {
		case -1:
			throw Exception(-1,"1");
			break;
		case -2:
			throw Exception(-2, "2");
			break;
		case -3:
			throw Exception(-3, "3");
			break;
		}
	}
}
int main() {
	try {
		Myfunc(11);
	}
	catch (const Base& b) {
		cout << "catch (const Base& b)" << endl;
	}
	catch (const Exception& e) {
		cout << e.id() << endl;
		cout << e.description() << endl;
	}
	return 0;
}

运行结果:catch (const Base& b)

6.C++标准库中提供了实用异常类族,标准库中的异常都是从exception类派生的,exception类有两个主要的分支

(1)logic_error常用于程序中的可避免逻辑错误

(2)runtime_error常用于程序中无法避免的恶性错误

相关推荐
xxxxxxllllllshi2 小时前
java值传递和引用传递的区别?举例一些常见都笔试面试题说明,最后有速记口诀
java·开发语言
HLC++2 小时前
C++中的类和对象
开发语言·c++
橙子也要努力变强2 小时前
Linux I/O 缓冲区、inode、软硬链接与磁盘结构全解析
linux·c++·操作系统
setmoon2142 小时前
C++与量子计算模拟
开发语言·c++·算法
KIKIiiiiiiii2 小时前
微信自动化机器人开发
java·开发语言·人工智能·python·微信·自动化
victory04312 小时前
containerd打包命令 和NFS挂载
java·开发语言
野犬寒鸦2 小时前
从零起步学习计算机操作系统:进程篇(知识扩展提升)
java·服务器·开发语言·后端·面试
※※冰馨※※2 小时前
【QT】System error #1455: 页面文件太小,无法完成操作
开发语言·windows·qt
Amnesia0_02 小时前
C++的异常
开发语言·c++·学习