c++primer 第十八章笔记 01异常处理

唉,代码都没有,真难受

18.1异常处理

第五章5.6节的 try catch语句块就是异常处理
它的机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并作出相应的处理

18.1.1抛出异常

if(item1.sibn()!=item2.sibn())
{
   
throw runtime_error("Dara must refer to same ISBN");
}
cout<<"item1+item2<<endl;

throwing表达式引发一个异常。被抛出的表达式的类型以及当前的调用链共同决定了那段处理代码
将被用来处理该异常。
1.一个异常如果没有被捕获,则它将终止当前的程序 一旦程序开始执行异常处理代码,沿着调用链创建的对象将被销毁
栈展开
栈展开就是程序寻找与异常匹配的catch语句,没有就在其他函数继续寻找。
栈展开过程沿着嵌套函数的调用链不断查找,直到找到了与异常匹配的catch子句为止,没有就执行terminate函数(终止程序的执行过程)
析构函数与异常
栈展开过程,运行类类型的局部对象的析构函数,这些析构函数自动运行,它们不应该抛出异常,一旦在栈展开的过程中析构函数抛出了异常,并且析构函数自身没能捕获到该异常,则程序将被终止
异常对象(一种特殊的对象)
当抛出了一条表达式时,该表达式的静态编译时类型决定了异常对象的类型,抛出指针要求在任何对应的处理代码存在的地方,指针所指的对象都必须存在

18.1.1节练习throw语句异常对象的类型是什么
(a)range_error r(“error”); throw r;
(b)exception *p =&r; throw *p;
异常对象r的类型是range_error;
(b)被抛出的异常对象是对指针p解引用的结果,其类型与静态类型相匹配,为exception,如果将(b)中的throw语句写成了
throw p,则抛出的异常对象是exception
类型**

练习18.2 当在指定的位置发生了异常时将出现什么情况 https://zhuanlan.zhihu.com/p/362408450-代码链接

void exercise(int*b,int*e)
{
   
vector<int>v(b,e);
int *p =new int[v.size()];
ifstream in("ints");
//此处发生异常
}

指针p指向的内存空间没有被释放造成内存泄露

练习18.3,让上面的代码在发生异常时能正常工作

void exercise(int* b, int* e)
{
   
	vector<int>v(b, e);
	int* p = new int[v.size()];
	try
	{
   
		ifstream in("ints");
	}
	catch (runtime_error t)
	{
   
		delete p;
	}
}

class Resource
{
   
public:
	Resource(size_t sz):p(new int[sz]){
   }
	~Resource()
	{
   
		if (p)
		{
   
			delete p;
		}
	}

private:
	int* p;

};

void exercise(int* b, int* e)
{
   
	vector<int>v(b, e);
	Resource p(v.size());

    ifstream in("ints");
	//此处发生异常
	
}

18.1.2 捕获异常

catch子句中的异常声明像是一个包含一个形参的函数形参列表,如果无须访问抛出的表达式忽略捕获形参的名字
声明的类型决定处理代码能捕获的异常类型,必须是完全类型,可以是左值引用不能是右值引用
catch参数是非引用类型,则该参数是异常对象的副本,而不是异常对象本身
参数是引用类型则改变参数就是改变异常对象
catch的参数是基类类型,可以用派生类类型的异常对象进行初始化,catch非引用类型则异常对象被切掉一部分,
参数是基类引用,参数将以常规方式绑定到异常对象
异常声明的静态类型决定catch语句所能执行的操作,catch参数是基类类型则无法使用派生类特有的任何成员
catch接受的异常与某个继承体系有关,则最好将该catch参数定义成引用类型

查找匹配的处理代码
异常和catch异常声明的匹配规则受到更多限制
1允许从非常量向常量的类型转换,一条非常量对象的throw语句可以匹配到一个接受常量引用的catch语句
2允许从派生类向基类的类型转换
数组被转换成指向数组(元素)类型的指针,函数被转换成指向该函数类型的指针(包括算术类型转换和类类型转换)
3 其他转换规则不能匹配catch的过程中使用
如果多个catch语句的类型之间存在着继承关系,应该把继承继承链最底端的类放在前面,而将最顶端的类放在后面

重新抛出
单独的catch语句不能完整地处理摸个异常,一条catch语句通过重新抛出的操作将异常传递给另外一个catch语句
catch语句可能会改变其参数的内容,只有当catch异常声明是引用类型才能改变

//这段代码的errCodes 貌似在编译器中没有,报错
	catch (my_error& eobj)//引用类型
	{
   
		eobj.status = errCodes::serverErr; //修改了异常对象
		throw;                             //异常对象的status成员是severeErr
	}
	catch (other_error eObj)              //非引用类型
	{
   
		eObj.status = errCodes::badErr;//只是修改看异常对象的局部副本
		throw;                         //s
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值