C++异常注意事项
C++里面catch对于类型转换,限制比参数传递时候要多:
不可以进行标准算术转换和类的自定义转换:在函数参数匹配的过程中,可以进行很多的类型转换。但是在异常匹配的过程中,转换的规则要严厉。
标准算术转换,指的是 short转成int 等等。异常catch的时候,不允许转换,指的是匹配的时候,就不会匹配上。比如下面:
#include <iostream>
#include <exception>
#include <stack> using namespace std; int main() {
std::cout << "Hello, World!" << std::endl; stack<int> stk;
//stk.push(5);
try {
//stk.pop();
short s = ;
throw s;
}
/*catch(runtime_error exception1) {
std::cout << exception1.what() << endl;
}*/
catch(int &x) {
std::cout << x << endl;
}
catch (...) {
cout << "here catch" << endl;
} return ;
}
输出:
here catch
意味着,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结构。
C++异常注意事项的更多相关文章
- 异常注意事项_多异常的捕获处理和异常注意事项_finally有return语句
异常注意事项_多异常的捕获处理 多个异常使用捕获又该如何处理呢? 1. 多个异常分别处理 2. 多个异常一次捕获,多次处理 3. 多个异常一次捕获一次处理 public class Demo01Exc ...
- Java 异常注意事项
异常的注意事项: 1,子类在覆盖父类方法时,父类的方法如果抛出了异常, 那么子类的方法只能抛出父类的异常或者该异常的子类. 2,如果父类抛出多个异常,那么子类只能抛出父类异常的子集. ...
- 重学c#系列——异常续[异常注意事项](七)
前言 对上节异常的补充,也可以说是异常使用的注意事项. 正文 减少try catch的使用 前面提及到,如果一个方法没有实现该方法的效果,那么就应该抛出异常. 如果有约定那么可以按照约定,如果约定有歧 ...
- java-异常-异常注意事项
1 package p1.exception; 2 3 /* 4 * 异常的注意事项: 5 * 6 * 1,子类在覆盖父类方法时,父类的方法如果抛出了异常, 7 * 那么子类的方法只能抛出父类的异常或 ...
- Java基础知识强化之IO流笔记08:异常的注意事项
1. 异常注意事项: (1)子类重写父类方法时候,子类的方法必须抛出相同的异常或者父类异常的子类.(父亲坏了,儿子不能比父亲更坏) (2)如果父类抛出多个异常,子类重写父类时候,只能抛出相同的异常或者 ...
- java异常及日志注意事项
一.异常注意事项 简单整理了下关于异常的规范: 1) 在异常处理模块中应提供精确.易读的错误原因信息. 2) 不要处理能够避免的异常. 3) 一个方法不应该抛出太多类型的 ...
- JavaEE基础(十九)/异常和File
1.异常(异常的概述和分类) A:异常的概述 异常就是Java程序在运行过程中出现的错误. B:异常的分类 通过API查看Throwable Error 服务器宕机,数据库崩溃等 Exception ...
- Java API —— 异常
1.异常:异常就是Java程序在运行过程中出现的错误. 2.异常由来:问题也是现实生活中一个具体事务,也可以通过java 的类的形式进行描述,并封装成对象.其实就是Java对不正常情况进行描述后的对象 ...
- 【Java基础】Java异常的一些总结
什么是异常 异常是指程序运行可能出现的不能正常继续的情况,也可以理解为程序出现了不在预期范围内的一些情况,都可以称之为异常. 异常的分类 所有的异常类是从java.lang.Exception类继承的 ...
随机推荐
- 【我所认知的BIOS】—> uEFI AHCI Driver(6) AtaAtapiPassThruSupported的局部变量们
[我所认知的BIOS]-> uEFI AHCI Driver(6) - AtaAtapiPassThruSupported的局部变量们 LightSeed 5/7/2014 前面5个篇文章把EF ...
- gcc 源代码分析-前端篇2
2. 对ID及保留字的处理 在c语言中,系统预留了非常多keyword.也被称为保留字,比方表示数据类型的int,short,char,控制分支运行的if,then等. 不论什么keyword, ...
- [HTML5] aria-label & aria-labelledby
'aria-labelledby' overwrite 'aria-label' overwirte native element label. TOP-LEFT: aria-label overwr ...
- node generator 模仿co
exports.run = function(fn ){ return function(onDone){ function thunk(tfn , ctx){ return function(sql ...
- Chrome下使用百度地图报错Cannot read property 'minZoom' of undefined
问题:工作中在Google chome下面的js console里面测试百度地图API var map = new BMap.Map("container"); map.cente ...
- 0x41 并查集
太菜了才做到并查集啊啊啊啊啊啊啊啊啊啊啊 还是很有收获的说 水 bzoj4195: [Noi2015]程序自动分析 好题 poj1456 感受到并查集传递性的美妙啊!对于一个商品,去找他过期前那天的集 ...
- hdoj--1272--小希的迷宫(并查集)
小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- Java IO 基础
早上复习了IO.NIO.AIO相关的概念,将其中一些要点记录一下. 从编程语言层面 BIO | NIO | AIO 以Java的角度,理解,linux c里也有AIO的概念(库),这些概念不知道什么原 ...
- hive2.0函数大全
Hive2.0函数大全(中文版) 摘要 Hive内部提供了很多函数给开发者使用,包括数学函数,类型转换函数,条件函数,字符函数,聚合函数,表生成函数等等,这些函数都统称为内置函数. 目录 数学函数 ...
- Java 系列之spring学习--springmvc搭建(四)
一.建立java web 项目 二.添加jar包 spring jar包下载地址http://repo.spring.io/release/org/springframework/spring/ 2. ...