对象资源管理及智能指针的简单用法

C++中的资源常常是动态分配内存,如果仅仅分配了,却不还给系统,就会造成内存泄漏。内存是众多资源中之一,其它常见资源还有GDI里的画笔,画刷对象,互斥锁mutex,数据库连接对象,socket等等,不管什么对象,不再使用时都需要返还给系统。

先看一段简单的代码:

A* A::create()
{
	A * temp = new A();
	return temp;
}
void A::f()
{
	A *pt = create();
	...<span style="white-space:pre">	</span>//某些其它操作
	delete pt;
}

上述代码中的 f  函数,调用了create函数,得到了一个对象指针,最后delete pt 看似没有任何问题,实际上如果省略号部分过早的return ,或者中间抛出了异常,那就接触不到下面的delete语句了,相同的情况在于delete位于一个循环中,但循环中某个部分break 了,那也不会触及delete,这样就造成了内存的泄漏。 

注:无论delete如何被略去的,我们泄漏的资源不仅仅是对象的那块内存,还包括对象所保存的任何资源。

我们在代码中,小心谨慎也许可以做到不泄漏,但代码也许会有其他人来维护,他们添加或删除一些return,break之类的,你的代码结构就被改变了,所以为了确保资源总是可以被释放,我们可以使用智能指针,其析构函数自动对其所指对象调用delete,下面就看改进后的写法:

void A::f()
{
	auto_ptr<A>pt(create());
//创建一个指针pt,类型为A *,初值为create函数的返回值
	....
}

这样,不论控制流如何离开区域块,一旦对象被销毁,其析构函数就会自动被调用,资源被释放。

注:由于auto_ptr 被销毁时会自动删除它所指之物,所以不能让auto_ptr指向同一个对象,不然就会造成一个对象被删除多次以上,产生未定义行为。


缺点:

若通过copy构造函数制,它们会变成NULL,复制所得的指针将获得唯一拥有权

看以下代码:

void A::f()
{
	auto_ptr<A>pt(create());
	auto_ptr<A>pt2(pt);//pt2指向对象,pt为NULL
	pt = pt2;//此时pt2为NULL
}
一系列诡异的复制,意味着auto_ptr还有需要改进的地方,这就引进了一个shared_ptr,他是引用计数型智慧指针,也就是说它会追踪共有多少对象指向某笔资源,并在无人指向时删除该资源。(有点像垃圾回收)

看下面改进代码

void A::f()
{
	shared_ptr<A>pt(create());
	shared_ptr<A>pt2(pt);//pt,pt2同时指向对象
	pt = pt2;//无区别
}
用法与auto_ptr完全相同,且复制如预期一般。所以它们可以用于STL容器以及其他 auto_ptr在复制行为不正确的情况。


最后,再说一个注意点:

不管是auto_ptr还是shared_ptr,它们都只是在析构函数中调用delete p;而不是delete []p; 所以如果是动态分配的数组的话切记不要用智能指针。虽然编译可能可以通过,但实际上还是泄漏了内存。对于数组,用vector,string等几乎完全替代动态分配得的数组。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值