Effective C++读书笔记----资源管理

  • C++中,我们自己申请的资源,需要我们手动的释放。

  • 有时候我们给了显示释放资源的语句,但是存在有些意外情况导致释放语句没能成功被执行。比如说在执行释放语句前函数提前返回;假如释放语句在一个循环内部,循环因为continue或者break提前结束;执行释放语句之前程序抛异常了。

  • 为了防止资源泄漏,请使用RAII对象(资源获得即初始化),他们在构造函数中获取资源,并在析构函数中释放资源。
  • auto_ptr防止同一个资源被多次释放(多个对象管理同一个资源)的方式为:对复制动作做特殊处理,被复制的对象将指向NULL(资源转移)。
  • shared_ptr使用引用计数的方式来防止同一个资源被多次释放,但是存在循环引用的问题(boost库中shared_ptr是线程安全的)。
  • 我们所说的资源不仅仅是指内存,还有文件描述符、锁、socket等。对于内存,将它释放掉就是将对应的指针释放掉,但是对于其他资源,比如文件描述符,释放动作是将对应的文件描述符关闭,而锁的释放动作是对一个已锁定的锁进行解锁。
  • shared_ptr中支持指定“删除器”,可以通过构造函数的第二个参数传递。auto_ptr执行的释放动作总是删除指针。
  • shared_ptr和auto_ptr都提供了get方法,用来执行显示转换,也就是它会返回智能指针内部的原始指针(的复件)。
  • shared_ptr和auto_ptr都重载了解引用“*”操作符,他们允许隐式转换为底层原始指针。
  • 对原始资源的访问可以通过显示转换或者隐式转换。一般而言,显示转换会比较安全,而隐式转换对客户来说比较方便。
  • new与delete一定要搭配使用,如果使用new的使用使用了[ ] ,在使用delete的时候也一定要使用[ ] ,否则很可能会造成内存泄漏。
  • 通过new动态生成一个对象时,会做两件事。

    1. 调用operator new函数分配内存
    2. 调用构造函数。(如果使用new时加了方括号[ ],也就是创建一个对象数组,会调用多次构造函数)
  • 使用delete,也会做两件事。

    1. 调用析构函数。
    2. 然后释放内存。(如果使用new的时候使用了[ ],在调用析构函数的时候也会调用对应次数的析构函数)
  • 数组的内存通常还包括‘数组大小’的记录,系统可以根据这个大小来决定调用构造函数和析构函数的次数。

  • 尽量不要对数组形式做typedef,有时候为了方便,将数组形式typedef为一个简单的类型,然后使用new,虽然new后边没有直接跟[ ] ,但是事实上它是相当于加了 [ ] 的。这样在后续使用delete的时候就有可能会忘记 [ ],因为很容易以为只是创建了一个单独的对象,而不是一个对象数组。
  • 使用单独的语句将newed得到的对象存储于智能指针中。如果不这样做,如果有异常抛出,就可能导致难以察觉的资源泄漏。
  • 对于 void processWidget (std::trl::shared_ptr pw, int priority) 这样一个函数。我们可以以如下的方式调用它:
  • processWidget (std::trl::shared_ptr (new Widget), priority())——-priority是一个返回值为int的函数,调用这个函数,将它的返回值作为实参传递给processWidget函数。

  • 这个函数调用语句会做三件事:

    1. 调用priority函数
    2. 执行new Widget
    3. 调用trl :: shared_ptr构造函数
  • 但是我们并不能确定priority函数和new Widget谁先被执行,如果是priority函数先被调用,然后执行 new Widget在将new Widget的结果作为构造函数的参数,这样无疑是没有任何问题的。但是如果是执行new Widget,然后再调用priority函数,如果在这个函数中抛出了异常,那么,new Widget的结果还没有来得及存储到一个智能指针中,它的返回值就会被遗失,也就引发了资源泄漏。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值