C++ 异常处理

1.语法

throw 表达式

try {
	语句块
}
catch (异常声明) {
	语句块
}
catch...
.
.
.

throw后表达式与异常声明匹配的规则
1.声明类型是抛出类型相同的类型或者同类型的引用
2.声明类型是抛出类型的公共基类其引用
3.皆为指针类型,抛出类型到声明类型可以隐式转换

2.例题-处理零异常

// 处理零异常
#include<iostream>
using namespace std;

int divide(int x, int y) {
	if (y == 0)
		throw x;
	return x / y;
}

int main() {
	try {
		cout << "5/2=" << divide(5, 2) << endl;
		cout << "8/0=" << divide(8, 0) << endl;
		// 抛出异常后剩余的语句不执行
		cout << "7/2=" << divide(7, 2) << endl;
	}
	// 与函数形参类似,匹配类型
	catch (int e) {
		cout << e << "is divided by zero!" << endl;
	}
	// 如果抛出的异常没有与catch里的值匹配的,会终止程序
	// 如果只给出异常声明中的类型,则不能访问这个变量
	cout << "That is ok" << endl;
	return 0;
}
/*
输出:
5/2=2
8is divided by zero!
That is ok
*/

3.异常接口声明

①一般格式(要求包含所有可能抛出的异常类型)

void fun() throw(A,B,C,D);

②可以抛出任何类型的异常

void fun();

③不抛出任何异常的函数

void fun() throw();

4.异常处理中的构造与析构

C++异常处理特性(栈的解旋):自动析构try块内,到异常被抛出前的所有建立的临时对象,且析构顺序与构造顺序相反

// 使用带析构语义的类的C++异常处理(栈的解旋)
#include<iostream>
#include<string>
using namespace std;

class MyException {
public:
	MyException(const string& message) : message(message) { cout << "构造一个MyExceotion" << endl; }
	~MyException() { cout << "析构一个MyException" << endl; }
	const string& getMessage() const { return message; }
private:
	string message;
};

class Demo {
public:
	Demo() { cout << "构造一个Demo" << endl; }
	~Demo() { cout << "析构一个Demo" << endl; }
};

void func() throw (MyException) {
	Demo d;
	cout << "Throw MyException in func()" << endl;
	// 抛出异常之前就析构在这个函数创建的Demo
	// 这里创建并且抛出一个异常对象
	throw MyException("exception thrown by func()");
}

int main() {
	cout << "In main function" << endl;
	try {
		func();
		// 抛出异常后的语句不会被执行,直接执行catch语句
		func();
	}
	// 也可以只有类型,没有具体的名字,但是那样不能访问抛出的对象
	catch (MyException& e) {
		cout << "Caught an exception:" << e.getMessage() << endl;
	}
	// 抛出异常后析构创建的异常对象
	cout << "Resume the execution of main()" << endl;
	return 0;
}
/*
输出:
In main function
构造一个Demo
Throw MyException in func()
构造一个MyExceotion
析构一个Demo
Caught an exception:exception thrown by func()
析构一个MyException
Resume the execution of main()
*/

5.例题-计算三角形面积

c++错误处理机制保证:

①对于以结点实现为基础的容器(list,set,map),要么成功,要么不对容器做任何改变

②对于以数组实现为基础的容器(vector),不能保证不被改变

// 计算三角形面积
#include<iostream>
#include<cmath>
// 包含异常处理头文件
#include<stdexcept>
using namespace std;

// 给出三角形三边长,计算三角形面积
// invalid_argument 表示向函数传入无效参数
double area(double a, double b, double c) throw (invalid_argument) {
	// 抛出一个异常后该函数直接结束
	// 判断边长是否为正
	if (a <= 0 || b <= 0 || c <= 0) {
		throw invalid_argument("the side length should be positive");
	}
	// 判断三边长是否满足三角不等式
	if (a + b <= c || b + c <= a || c + a <= b) {
		throw invalid_argument("the side should fit the triangle inequation");
	}
	// Heron公式
	double s = (a + b + c) / 2;
	return sqrt(s * (s - a) * (s - b) * (s - c));
}

int main() {
	double a, b, c;
	cout << "Please input:";
	cin >> a >> b >> c;
	try {
		double s = area(a, b, c);
		// 抛出异常没有接下来的输出语句
		cout << "area:" << s << endl;
	}
	catch (exception& e) {
        // what 函数可以获得构造时给出的错误信息
		cout << "ERROR:" << e.what() << endl;
	}
	return 0;
}

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值