智能指针scoped_ptr,shared_ptr,weak_ptr和auto_ptr的使用

来源:互联网 发布:网络名称大全 编辑:程序博客网 时间:2024/05/01 03:58

通常在类中含有指针的话,需要对赋值操作符和拷贝构造函数进行重新定义,然而这些会引起一些歧义和不便,简单来说,赋值操作符是将原内存区的地址赋给新对象还是令新对象开辟新的内存区,再把原内存区的值赋值到新内存区呢?如果是只把地址赋给新对象,那什么时候释放内存?

由于指针的这些问题,类对于指针的处理方式有以下三种:

1、常规指针行为。该方式直接将地址赋给新对象,不会对内存的释放进行控制,但是无需特殊的复制控制。

2、取值型行为。该方式通过重新定义复制控制,使得每个指针所指向的内存区域是唯一的,也就是每个对象中的指针指向单独的内存区域,不被共享,也就是说复制控制中需要重新开辟内存和复制原始内存区的值到新内存区。

3、智能指针行为。该方式指针指向的内存区域可以是共享的,但是类能够防止方式一导致的悬垂指针。


本文想要谈的也就是智能指针,在C++ primer中,作者通过一个计数类来保存指针和计数以实现智能指针。感兴趣的可以去看13.5,接下来我们要谈谈智能指针类,也就是一些库中提供的智能指针类模板。

scoped_ptr,shared_ptr和weak_ptr这三个都来自于boost库中。auto_ptr是C++标准库中(<utility>)。

auto_ptr与boost库中的share_ptr不同的,auto_ptr没有考虑引用计数,因此一个对象只能由一个auto_ptr所拥有,在给其他auto_ptr赋值的时候,会转移这种拥有关系。关于auto_ptr有以下几点需要注意:

1、所以不能使两个auto_ptr指向同一个对象。

int* p = new int(0);auto_ptr<int> ap1(p);auto_ptr<int> ap2(p);
这里ap1和ap2都认为p是属于自己的,当两者都析构后,会释放两次p,这在c++里是未被定义的。

2、不应该用auto_ptr来管理一个数组指针。

在auto_ptr的析构函数里,使用的是delete而不是delete[]

3、由于auto_ptr的转移特性,不能用于容器中和一些算法,容器中有太多赋值操作了。

4、当auto_ptr作为作为函数参数按值传递时,会有复制操作,也就是说原本的auto_ptr失去了对指针的控制,当函数结束,该auto_ptr指针变成了NULL。

更多特性和代码阅读请参考下方链接:

http://www.cppblog.com/SmartPtr/archive/2007/07/05/27549.html


scoped_ptr:

使用boost::scoped_ptr时,包含头文件"boost/scoped_ptr.hpp"。boost::scoped_ptr 用于确保动态分配的对象能够被正确地删除。scoped_ptr 有着与std::auto_ptr类似的特性,而最大的区别在于它不能转让所有权而auto_ptr可以。事实上,scoped_ptr永远不能被复制或被赋值!scoped_ptr 拥有它所指向的资源的所有权,并永远不会放弃这个所有权。

scoped_ptr. 它是一种轻量级的智能指针;使用它不会使你的程序变大或变慢。它只会让你的代码更安全,更好维护。


shared_ptr:
shared_ptr的一个重要目的就是为了提供一个标准的共享所有权的智能指针。
shared_ptr就是为了解决auto_ptr在对象所有权上的局限性(auto_ptr是独占的),在使用引用计数的机制上提供了可以共享所有权的智能指针。shared_ptr是可以拷贝和赋值的,拷贝行为也是等价的,并且可以被比较,这意味这它可被放入标准库的一般容器(vector,list)和关联容器中(map)。


weak_ptr:
weak_ptr是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作,它可以从一个shared_ptr或另一个weak_ptr对象构造,它的构造和析构不会引起引用记数的增加或减少。没有重载*和->但可以使用lock获得一个可用的shared_ptr对象,使对象自己能够生产shared_ptr来管理自己。

引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引用的对象。通过boost::weak_ptr来打破循环引用,由于弱引用不更改引用计数,类似普通指针,只要把循环引用的一方使用弱引用,即可解除循环引用。


0 0
原创粉丝点击