C++构造函数、析构函数与抛出异常
来源:互联网 发布:c语言两条竖线 编辑:程序博客网 时间:2024/05/29 23:47
C++构造
C++构造函数、析构函数与抛出异常
【本文链接】
http://www.cnblogs.com/hellogiser/p/constructor-destructor-exceptions.html
【问题】
构造函数可以抛出异常么?析构函数可以吗?
【分析】
从语法上来说,构造函数和析构函数都可以抛出异常。但从逻辑上和风险控制上,构造函数可以,析构函数不推荐抛出异常。
(1)构造函数可以抛出异常
无论何时,从构造函数中抛出异常都是可以的。动态创建对象要进行两个操作:分配内存和调用构造函数。若在分配内存时出错,会抛出bad_alloc异常;若在调用构造函数初始化时出错,会不会存在内存泄漏呢?答案是不会。
new运算符保证不会出现内存泄漏:
将被编译器转换给类似下面的样子:
2
3
4
5
6
7
8
9
10
11
12
13
14
{
// 第一步,分配原始内存,若失败则抛出bad_alloc异常
try
{
// 第二步,调用构造函数构造对象
new (p)T; // placement new: 只调用T的构造函数
}
catch(...)
{
delete p; // 释放第一步分配的内存
throw; // 重抛异常,通知应用程序
}
}
(2)析构函数不推荐抛出异常,如果析构函数可能抛出异常,那么必须要求在析构函数内消化所有异常或者结束程序。
more effective c++提出两点理由(析构函数不能抛出异常的理由)
1)如果析构函数抛出异常,则异常点之后的程序不会执行,如果析构函数在异常点之后执行了某些必要的动作比如释放某些资源,则这些动作不会执行,会造成诸如资源泄漏的问题。 [正常情况下调用析构函数抛出异常导致资源泄露]
2)通常异常发生时,c++的机制会调用已经构造对象的析构函数来释放资源,此时若析构函数本身也抛出异常,则前一个异常尚未处理,又有新的异常,会造成程序崩溃的问题。 [在发生异常的情况下调用析构函数抛出异常,会导致程序崩溃]
解决方案:
1) 如果某个操作可能会抛出异常,class应提供一个普通函数(而非析构函数),来执行该操作。目的是给客户一个处理错误的机会。
2) 如果析构函数中异常非抛不可,那就用try catch来将异常吞下,必须要把这种可能发生的异常完全封装在析构函数内部,决不能让它抛出函数之外。
【参考】
http://blog.csdn.net/liuxialong/article/details/6586083
http://www.cnblogs.com/fly1988happy/archive/2012/04/11/2442765.html
http://www.cnblogs.com/KevinSong/p/3323372.html
- 构造函数与析构函数中抛出异常
- 构造函数、析构函数 与抛出异常
- C++构造函数、析构函数与抛出异常
- 构造函数与析构函数是否可以抛出异常
- C++构造函数、析构函数与抛出异常
- 构造函数、析构函数抛出异常
- 构造函数析构函数抛出异常
- 【effective c++】C++构造函数、析构函数与抛出异常
- 构造函数 抛出异常
- 构造函数抛出异常
- [c/c++]构造函数、析构函数中可不可以抛出异常
- 构造函数中可不可以抛出异常?析构函数呢?
- 构造函数、析构函数抛出异常的问题
- 构造函数、析构函数抛出异常的问题
- 构造函数、析构函数可以抛出异常吗?为什么?
- 构造函数和析构函数中抛出异常
- 构造函数、析构函数抛出异常的问题
- 构造函数、析构函数抛出异常的问题
- 微信小程序开发 ---- 1
- Stm32 Bootloader整理
- 面试记录
- 本地浏览器远程使用linux下的jupyter
- 由于未修改主机名导致的yarn框架错误
- C++构造函数、析构函数与抛出异常
- jquery获取td中的input
- Linux学习笔记:bash的配置文件
- 10个免费的顶级跨浏览器测试工具
- 修改VMware虚拟机内部Linux系统的默认分辨率
- Java中的基本数据类型与引用数据类型
- 面向切面的 Spring —— 如何通过切点来选择连接点?
- Linux 内存优化
- 抽象类和接口