博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++异常注意事项
阅读量:6550 次
发布时间:2019-06-24

本文共 1694 字,大约阅读时间需要 5 分钟。

C++里面catch对于类型转换,限制比参数传递时候要多:

不可以进行标准算术转换类的自定义转换:在函数参数匹配的过程中,可以进行很多的类型转换。但是在异常匹配的过程中,转换的规则要严厉。

 

标准算术转换,指的是 short转成int 等等。异常catch的时候,不允许转换,指的是匹配的时候,就不会匹配上。比如下面:

#include 
#include
#include
using namespace std;int main() { std::cout << "Hello, World!" << std::endl; stack
stk; //stk.push(5); try { //stk.pop(); short s = 5; throw s; } /*catch(runtime_error exception1) { std::cout << exception1.what() << endl; }*/ catch(int &x) { std::cout << x << endl; } catch (...) { cout << "here catch" << endl; } return 0;}
View Code

输出:

here catch
View Code

意味着,int对于short的catch没有接住。

 

另外,异常处理机制的匹配过程是寻找最先匹配(first fit),函数调用的过程是寻找最佳匹配(best fit)。

 

拷贝代价

如果throw中抛出一个对象,那么无论是catch中使用什么接收(基类对象、引用、指针或者子类对象、引用、指针),在传递到catch之前,编译器都会另外构造一个对象的副本。也就是说,如果你以一个throw语句中抛出一个对象类型,在catch处通过也是通过一个对象接收,那么该对象经历了两次复制,即调用了两次复制构造函数。

一次是在throw时,将“抛出到对象”复制到一个“临时对象”(这一步是必须的),然后是因为catch处使用对象接收,那么需要再从“临时对象”复制到“catch的形参变量”中; 如果你在catch中使用“引用”来接收参数,那么不需要第二次复制,即形参的引用指向临时变量。 

 

析构、构造函数

 2. 析构函数应该从不抛出异常。如果析构函数中需要执行可能会抛出异常的代码,那么就应该在析构函数内部将这个异常进行处理,而不是将异常抛出去。

                     原因:在为某个异常进行栈展开时,析构函数如果又抛出自己的未经处理另一个异常,将会导致调用标准库 terminate 函数。而默认的terminate 函数将调用 abort 函数,强制从整个程序非正常退出。

               3. 构造函数中可以抛出异常。但是要注意到:如果构造函数因为异常而退出,那么该类的析构函数就得不到执行。所以要手动销毁在异常抛出前已经构造的部分。

 

具体可以看这一篇的说明:

http://www.cnblogs.com/zhyg6516/archive/2011/03/08/1977007.html

Linux的进程布局可以看:

http://www.cnblogs.com/charlesblc/p/6415916.html

具体讲,析构函数不能抛出异常,是因为只有析构函数抛出异常没问题,但是如果有其他函数抛出异常,并且调用了析构函数抛出异常的处理,那么会造成SEH的异常处理链的混乱。

 

 

构造函数可以抛出异常,但是不建议。

需要处理掉已经声明的内存,或者用RAII.

 

 

对于多线程,异常是安全的

对于每一个线程都有自己的 Thread Info/Environment Block. 维护自己的SEH结构。

 

你可能感兴趣的文章
各个平台 如何安装 Ruby 和 RubyGems
查看>>
九. 200创业教训万元获得--“神刻”这是忽悠?
查看>>
eclipse maven plugin 插件 安装 和 配置
查看>>
Swift - 控制流/控制结构说明(if,switch,for,while)
查看>>
五个有用的jquery小技巧
查看>>
算法-三向字符串快速排序
查看>>
Spring 3.1新特性之二:@Enable*注解的源码,spring源码分析之定时任务Scheduled注解
查看>>
Oracle DISTINCT A 排序问题(转)
查看>>
Objective-C:KVC机制
查看>>
身份证查询API
查看>>
iText5报表_页眉与页脚
查看>>
javascript:void(0) ,设置a链接无效,设置点击a页面不刷新,不跳动
查看>>
两台linux服务器之间实现挂载
查看>>
keyup与setInterval
查看>>
python --批量重命名文件名
查看>>
QQ三方登录
查看>>
NTP方式保证以时间戳同步可靠性
查看>>
开源的服务发现
查看>>
lucene.net 使用过程中的 几个注意事项(含termquery 和QueryParser 的区别)
查看>>
Android开发之音乐播放器的实现
查看>>