10 在构造函数防止资源泄漏
2021/8/19 23:07:23
本文主要是介绍10 在构造函数防止资源泄漏,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
有以下构造函数和析构函数:
BookEntry::BookEntry() : pImage(nullptr) , pClip(nullptr) { pImage = new Image(); pClip = new Clip(); } ~BookEntry() { delete pImage; delete pClip; }
构造函数在初始化列表将指针pImage
、pClip
置空,然后在函数内为指针初始化对象。在析构函数释放指针的资源,避免内存泄漏。
在正常情况下运行良好,但当pClip = new Clip();
这一步发生错误时,异常将会被BookEntry构造函数
的调用者。错误的原因可能是operator new
不能分配足够的内存,或是Clip
的构造函数发生异常。
__发生异常的BookEntry
对象并没有完成构造。C++仅能删除被完全构造的对象,即构造函数完全运行完毕,因此~BookEntry()
永久不会被调用,导致了内存泄漏。__如果尝试主动捕获异常并调用析构函数:
try { BookEntry * obj = new BookEntry(); } catch(...) { delete obj; throw; }
__new
首先通过operator new
分配堆内存,然后调用相应的构造函数,最后将内存首地址返回到指针。当BookEntry
的构造函数发生异常时,obj
仍然是空指针,delete obj
并不能释放掉已分配的堆内存。__因此对象必须在构造函数发生异常时,在构造函数内执行必要的清除工作。
BookEntry::BookEntry() : pImage(nullptr) , pClip(nullptr) { try { pImage = new Image(); pClip = new Clip(); } catch(...) { delete pImage;//删除空指针是安全的 delete pClip; throw; } }
如果是Clip
的构造函数发生异常,构造函数能够将已分配内存的pImage
资源释放,但对于Clip
对象中可能泄漏的资源,它的构造函数需要用同样的方法进行清除:构造函数在异常传递之前完成必要的清除工作。
当pImage
和pClip
是常量指针,必须要成员初始化列表完成构造,上述的方法不再适用。同时,初始化列表只允许表达式,try
和catch
必须转移到别的地方。
- 在成员函数中完成初始化
BookEntry::BookEntry() : pImage(initImage())//通过私有构造函数初始化对象 , pClip(initClip()) {} Image * BookEntry::initImage() { return new Image(); } Clip * BookEntry::initClip() { try { return new Clip(); } catch(...) {//因为`Clip`在`pImage`之后构造,其初始化函数负责释放`pImage`资源。 delete pImage; } }
- 把对象指针作为一个资源,被一个局部对象管理,如智能指针。
class BookEntry { public: BookEntry(); ~BookEntry() = default;//资源自动释放 private: const auto_ptr<Image> pImage; const auto_ptr<Clip> pClip; } BookEntry::BookEntry() : pImage(new Image) , pClip(new Clip) {}
通过智能指针简化构造函数中的异常处理:当new Clip
发生异常时,智能指针pImage
是已经完全构造的局部对象,在离开生命周期后会自动释放掉,因此不需要再手动捕获异常来进行清除。同时由局部对象管理动态资源,省略了析构函数中的清除操作。
这篇关于10 在构造函数防止资源泄漏的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-01为什么公共事业机构会偏爱 TiDB :TiDB 数据库在某省妇幼健康管理系统的应用
- 2024-04-26敏捷开发:想要快速交付就必须舍弃产品质量?
- 2024-04-26静态代码分析的这些好处,我竟然都不知道?
- 2024-04-26你在测试金字塔的哪一层?(下)
- 2024-04-26快刀斩乱麻,DevOps让代码评审也自动起来
- 2024-04-262024年最好用的10款ER图神器!
- 2024-04-2203-为啥大模型LLM还没能完全替代你?
- 2024-04-2101-大语言模型发展
- 2024-04-17基于SpringWeb MultipartFile文件上传、下载功能
- 2024-04-14个人开发者,Spring Boot 项目如何部署