《Effective C++》资源管理章节
Item 13:以对象管理资源
关键的两个想法(这种方式其实在很多地方都可以看出影子,比如managing pool的模型):
1.获得资源后立刻放入管理对象(managing object):以对象管理资源的观念常常被称为“资源取得之时就是初始化时机”(Resourece Acquisition Is Initialization;RAII),因为我们总是在获得资源后,在同一语句内用它来初始化某个管理对象。有时候获得的资源被拿来赋值(而非初始化)某个管理对象。但不管哪一种做法,每一笔资源都在获得的同时立刻被放入管理对象中。
2.管理对象(managing object)运用析构函数确保资源被释放:不管控制流如何离开区域块,一旦对象被销毁(例如当对象离开作用域时),其析构函数自然会被自动调用,于是资源被释放。如果资源释放动作可能抛出异常,事情就变的有些棘手了(可以参考item8)。
总结:
1.为防止泄漏资源,请使用RAII对象,它们在构造函数中获得资源并且在析构函数中释放资源。
2.两个常被使用的RAII classes是shared_ptr和auto_ptr。前者通常是最佳选择,因为其copy行为比较直观。若选择auto_ptr,复制动作会使它(被复制物)指向null。
Item 14:在资源管理类中要小心copying行为
对于那些并不是在heap-based的资源,采用auto_ptr,shared_ptr并不是一个好方法,这时候我们需要自己建立一个管理类,这时候我们就会面临一个问题:“当一个RAII class被复制时候,我们要怎么选择?”
1.禁止复制。如Item6中告诉我们的,可以将赋值构造函数和操作符设置为private:
class Lock
{
private:
void operator=(){};
Lock(const Lock&){};
}
2.对底层资源使用“引用计数法”。有时候我们希望保有资源,直到它的最后一个使用者(某对象)被销毁。这种情况下复制RAII对象,应该将该资源的count变量+1,shared_ptr就是如此。
3.复制底部资源。
4.转移底部资源控制权。这一条就是auto_ptr所奉行的复制意义。
总结:
1.复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。
2.普遍而常见的RAII class copying行为是:抑制copying、实施引用计数法。不过其他的行为也可能被实现。
Item15:在资源管理类中提供对原始资源的访问
总结:
1.APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其管理的资源的方法”。
2.对原始资源的访问可能经由显式或者隐式转换。一般而言显式转换比较安全,但隐式转换对客户比较方便。
Item16:成对使用new和delete时要采取相同的形式
总结:如果你在new表达式中使用了[],必须在相对应的delete表达式中也使用[]。如果你在new的表达式中没有使用[],一定不要在相应的delete表达式中使用[]。
(不管是哪一种情况搞反了,都会导致未定义的结果)
Item17:以独立语句将newed对象置入智能指针
总结:以独立语句将newed对象存储于智能指针中。如果不这么做,一旦异常被抛出,有可能导致难以察觉的内存泄漏。
作者:lizhenghao126
出处:https://www.cnblogs.com/lizhenghao126/p/11053756.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)