Effective C++学习笔记(四)资源管理、内存泄漏

Effective C++学习笔记(四)

条款 13 以对象管理资源
使用了资源后就一定要归还给系统,比如内存资源,如果不归还就会造成内存泄漏。
就是依赖析构函数自动调用的机制,归还资源。使用RAII机制,在对象的构造函数中获得资源,在析构函数中释放资源。
两个管理指针的类:
(1)auto_ptr
若通过copy构造或者copy赋值复制他们,他们自身会变成NULL,而复制所得的指针将得到资源的唯一拥有权。即只会有一个指针指向一片资源
(2)shared_ptr
引用计数型智慧指针,它持续追踪共有多少个对象指向某笔资源,并在无人指向它时自动删除该资源
使用范例:

class investment{};
investment* creat_investment();
void f()
{
	investment* pinv =  creat_investment();
	....
	//这样是极易造成内存泄漏的,因为程序在没到达此处之前很有可能发生异常,或者退出等,不会触及delete语句
	delete pinv;
}

void f()
{
	investment* pinv =  creat_investment();
	....
	std::auto_ptr<investment> pinc = creat_investment();
	//这样在调用creat_investment函数时,系统创建auto_ptr对象,在退出时调用析构函数释放
}
auto_ptr<int> p1 = new int(1);
p1 = p2;  //p1 为NULL p2指向原来p1指向的位置
auto_ptr<int> p3(p2) //p2 为NULL p3指向p2原来指向的区域

void f()
{
	investment* pinv =  creat_investment();
	....
	std::tr1::shared_ptr<investment> pinc = creat_investment();
	//这样在调用creat_investment函数时,系统创建shared_ptr对象,在退出时调用析构函数释放
}
shared_ptr<int> p1 = new int(1);
p1 = p2;  //p1、p2指向原来p1指向的位置
auto_ptr<int> p3(p2) //p3指向p1、p2指向的区域

条款 14 在资源管理类中小心copying行为
(1)复制RAII对象必须一并复制他所管理的资源,所以资源的copying行为决定了RAII对象的copying行为
(2)普遍而常见的RAII class copying行为是:抑制copying(将copying函数设为private)、施行引用计数法(shared_ptr)另外还用:复制底部资源即深拷贝、转移底部资源的拥有权(auto_ptr)

条款 15 在资源管理类中提供对原始资源的访问
每一个RAII class应该提供一个“取得其所管理之资源的方法”;
auto_ptr 和 shared_ptr都提供了get()函数,可以获得原始指针。另外也重载了 operator -> 和 operator * 可以让其像指针一样进行操作。(page 70);
对原始资源的访问可能经由显示转换或隐式转换,显示转换就是提供一个接口,返回所管理的对象,这样做比较安全。但是隐式转换使用更方便,但是会造成意想不到的问题,例如在拷贝时。

条款16 成对使用new和delete时要采取相同的形式
调用new时:先分配足够的内存空间,然后调用一个或多个构造函数
调用delete时:先调用一个或多个析构函数,然后释放内存空间
delete的问题在于,即将要被删除的空间中含有多少个对象,即要调用多少次析构函数。
对于单一对象的内存布局不同于数组的内存布局,数组所用的内存通常还包括“数组大小”的记录,以便告诉delete需要调用几次析构函数;
new时带[] delete []
new时不带[] -》 delete 注意typedef的情况,尽量不要对数组进行typedef,这样在new和delete时会造成不成对的情况

条款17 以独立语句将newed对象置入智能指针
举例:

//1.shared_ptr 构造函数时explicit的所以参数一不能直接写 new widget
process(shared_ptr<widget>(new widget),proprity()); 
/*
上述语句会做三件事情:
1.调用priority
2.执行“new Widget”
3.调用 shared_ptr构造函数
如果调用顺序是这样的:
1.执行“new Widget”
2.调用priority
3.调用 shared_ptr构造函数
那么如果在调用priority时发生了异常,就会造成内存泄露,因为智能指针此时还没有管理new出来的指针
*/

//正确做法
shared_ptr<widget> pw(new widget)
process(shared_ptr<widget>(pw,proprity());
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值