构造函数应该尽量避免产生异常
来源:互联网 发布:淘宝低价交易风险通知 编辑:程序博客网 时间:2024/06/08 09:38
构造函数应该尽量避免产生异常
1.说明
构造函数是对一个对象进行初始化,一般来说,构造函数不应该设计的太复杂,即只进行简单的成员变量的初始化即可,这样就可以更好的保证构造函数不会产生异常。
2.构造函数产生异常的危害
C++在进行实例化对象,当调用构造函数的过程中发生异常时,这将导致无法调用对象的析构函数,这时仅仅清理和释放产生异常前的那些C++管理的变量空间等,而我们动态申请的资源(通过析构函数释放)是无法自动释放的,这将会导致资源泄露。
3.解决构造函数出现的异常
如果你的构造函数,不仅仅是进行简单的成员变量的初始化,还需涉及到了一系列资源的分配,可以通过下述方法解决:容易出现资源泄露代码如下:
class Test{public: Test() {/* pA = new A(), 注意了,这里针对的是动态分配资源,失败返回NULL,进行DELETE NULL不会出现异常,如果是其他资源,这里出现异常需要额外的处理, 即需要考虑资源失败和成功的不同处理方式,例如,对互斥器未加锁的情况下进行解锁,会导致未定义行为。*/ pA = new A(); ... } ~Test() { delete pA;... }private: A* pA;};
(1)、方法一:通过异常处理机制,一旦发生异常,先进行资源的释放
Test::Test(){ try { pA = new A(); //资源的异常,资源申请失败也就谈不上释放资源了,更主要考虑的是,申请资源成功后的下面的异常。 ... } catch (...) { if(NULL != pA) { delete pA; } throw; //抛出对应异常,交给上层处理 } }
(2)、方法二:通过智能指针进行管理
class Test{public: Test() { spA = std::make_shared<A>; //资源由智能指针进行处理 ... } ~Test() { }private: std::shared_ptr< A > spA;};
(3)、方法三:把资源申请和释放的操作存放在另外的Init()和Release()函数
class Test{public: Test() { pA = NULL; if (!Init()){ Release();}... } ~Test() { Release(); } private: bool Init() { try { pA = new A(); //资源的异常,资源申请失败也就谈不上释放资源了,更主要考虑的是,申请资源成功后的下面的异常。 ... } catch (...) { return false; } } return true; } void Release() { if(NULL != pA) { delete pA; pA = NULL; } }private: A* pA; };
总结:
(1)、构造函数中发生异常,会导致析构函数不能被调用,但对象本身已申请到的内存资源会被系统释放(已申请到资源的内部成员变量会被系统依次逆序调用其析构函数)。
(2)、由于析构函数不能被调用,这就可能会造成内存泄露或系统资源未被释放。
(3)、构造函数中如果发生异常,必须在构造函数抛出异常之前,把系统资源释放掉,以防止内存泄露。
0 0
- 构造函数应该尽量避免产生异常
- 构造函数中尽量不要抛出异常,能避免的就避免。。不要在析构函数中抛出异常!
- 我应该尽量避免不幸
- 构造函数尽量简化
- 程序员为什么应该尽量避免争吵
- 提高C#编程水平的50个要点 之十六“尽量避免产生资源垃圾”
- 异常和构造函数
- 构造函数抛异常
- 关于构造函数异常
- 构造函数 抛出异常
- 构造函数抛出异常
- ASP.NET : 为什么应该尽量避免直接用Response.Write输出内容
- 尽量避免官司缠身
- 尽量使用初始化而不要在构造函数里赋值
- 尽量使用初始化而不要在构造函数里赋值
- 尽量使用初始化而不要在构造函数里赋值
- 避免无用的缺省构造函数
- 避免无用的缺省构造函数
- 序列化与反序列化
- 5. PHP接入支付宝单笔订单查询接口
- iOS 完美解决导航栏在页面切换时隐藏与显示的动画
- linux commen cmd
- 【郑轻】[1897]985的红绿灯难题
- 构造函数应该尽量避免产生异常
- 1、GreenDao封装后使用
- PAT-A 1069. The Black Hole of Numbers
- [个人总结]Code Review
- 【网络学习】通过无线,桥接2个路由器
- Maven依赖(一)
- win7与vmware实现文件共享
- EL表达式与JSTL标签库示例
- 使用链表编写的通讯录