C++:异常

longjmp和setjmp

setjmp(buff)返回值是0,设置long的跳转点,setjmp执行完后,内部会将当前程序所有的寄存器信息和数据保存到buff中

#include <setjmp.h>

jmp_buf buff;

void Func1()
{
	FILE* pf = fopen("1111.txt", "rb");
	if (nullptr == pf)
	{
		longjmp(buff, 1);
	}

	// ...
	fclose(pf);
}

void Func2()
{
	char* p = (char*)malloc(0x7fffffff);
	if (nullptr == p)
	{
		longjmp(buff, 2);
	}

	// ...
	free(p);
}

int main()
{
	// 在设置程序的跳转点,
	// setjmp执行完成之后,会把当前位置的寄存器信息会保存到buff中
	// 然后setjmp返回0
	int istate = setjmp(buff);
	if (0 == istate)
	{
		// 执行程序的正常逻辑
		Func2();
		Func1();
	}
	else
	{
		// 错误处理
		switch (istate)
		{
		case 1:
			cout << "Func1中的fopen打开文件失败" << endl;
			break;
		case 2:
			cout << "Func2中的malloc申请空间失败" << endl;
			break;
		default:
			cout << "为止错误" << endl;
			break;
		}
	}
	
	return 0;
}

异常

  • throw: 当问题出现时,程序会抛出一个异常
    错误发生后,不想在函数体内处理,想让函数的调用者处理,或者调用的调用者处理
    throw 后可以跟数字,变量,对象
  • catch: 捕获异常,可以有多个catch进行捕获
    捕获throw后跟的东西
    catch(int err)类似于函数的形参
  • try: try 块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个 catch 块。

new运算符的operator new函数中,有一个_RAIS宏,内部封装了throw
vector中的at函数会抛出异常

  • 异常是按照类型捕获的,throw 1是抛出整形异常,异常编号是1,异常不会发生类型转换
    对所有可能抛出异常的代码都要捕获
  • 有异常被抛出,如果当前存在异常的函数没有捕获,则异常会从函数中出来,进入调用者的作用域,被最近的匹配的类型捕获
  • 抛出的异常是一个临时对象,这个临时对象被catch后销毁
    -异常的重新抛出: catch(...)捕获任意异常,捕获到异常后,不处理它又再次抛出
  • 抛子类的异常,可以在catch中用父类对象接收

栈展开:异常被抛出后,没有在本函数内捕获,会逐层抛给调用者,直到被捕获

异常安全

由异常引起的安全问题
不要在构造和析构中抛异常,这样可能导致对象初始化和释放的不完整

异常规范

在这里插入图片描述
使func3函数只能抛整形异常
括号中不写,表示函数不能抛出异常,否则编译失败

基本不抛内置类型异常

在这里插入图片描述

直接抛exception类对象,重写父类的what方法,调用what方法就知道哪个子类有问题了
不同子类对象含义不一样

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值