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常用于程序中无法避免的恶性错误

相关推荐
§ꦿCFོ༉6 小时前
嵌入式八股文—C语言入门学习(四)
c语言·开发语言·学习
投图匠6 小时前
十种不同风格的 CTP接口 框架
开发语言·python
爱笑的k119 小时前
nano-vllm 源码剖析:千行 Python 手写离线推理引擎的调度、显存与并行时序
开发语言·python·vllm
X1A0RAN10 小时前
PPT 图片批量处理教程:导出全部幻灯片 · 提取全部素材
开发语言·javascript·powerpoint
熊猫钓鱼>_>12 小时前
普通用户视角的端侧智能体验手记【鸿蒙心迹】
开发语言·人工智能·华为·智能手机·性能优化·ai编程·harmonyos
瑞雪兆丰年兮12 小时前
JavaWeb-day13-SpringBootWeb事务管理&AOP
java·开发语言·springboot·javaweb·事务·web·aop
布莱克60513 小时前
Swift 常量详解:从 let 到编译期优化
服务器·开发语言·ssh·swift·常量·let
布莱克60514 小时前
Swift 可选类型(Optionals)详解:从原理到实战
开发语言·安全·ssh·swift·optional·可选类型
老歌老听老掉牙14 小时前
案例 7:二维 Rosenbrock 函数最小值(香蕉函数)
c++·pso
Severus_black15 小时前
【C++初阶】Stack、Queue算法题大练兵!
c语言·c++·算法·stl