C++智能指针:auto_ptr、shared_ptr、weak_ptr等

来源:互联网 发布:陕西省大数据集团领导 编辑:程序博客网 时间:2024/05/22 10:50

一 C++对含有指针成员的类的处理:

(1)指针成员采取常规指针型行为。这样的类具有指针的所有缺陷(比如:悬挂指针)但无需特殊的复制控制。
(2)类可以实现“智能指针”行为。指针所指的对象是共享的,但类能够防止悬挂指针。(引用计数)

*智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。每次创建类的新对象时,初始化指针并将引用计数置为1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;调用析构函数时,析构函数减少引用计数(如果引用计数减至0,则删除基础对象)。

*实现引用计数有两种经典策略:一是引入辅助类,二是使用句柄(handle)类

(3)类采取值型行为(深拷贝。指针所指的对象是唯一的,由每个类对象独立管理。

智能指针:
*RAII机制:资源获得时便初始化(以对象管理资源)。
*C++标准提供的有:auto_ptr和tr1::shared_ptr。
*C++ tr1是针对C++标准库的第一次扩展。即将到来的下一个版本的C++标准会包括它,以及一些语言本身的扩充。
*boost.smart_ptr库提供了六种智能指针:scoped_ptr、scoped_array、shared_ptr、shared_array、weak_ptr和instrusive_ptr。其中shared_ptr和weak_ptr已被收入到c++标准的TR1库中。

(一)auto_ptr:
1)使用方法:auto_ptr定义在头文件auto_ptr.h中,使用时需#include<memory>。

2)auto_ptr特点:
*auto_ptr之间不能共享拥有权。拷贝和赋值动作将引发auto_ptr的拥有权转移。例如:ptr2=ptr1,拥有权将从ptr1转移至ptr2。释放拥有权代码如下:
T *release() throw(){T *temp(ap);ap=0;//并没有释放资源,只是将指针致为0return temp;}

*不存在针对array而设计的auto_ptr。因为auto_ptr是透露delete而非delete[]来释放其所拥有的对象。
*auto_ptr不是引用计数型指针。
*auto_ptr不满足STL容器对其元素的要求。因为在拷贝或者赋值动作之后,原来的auto_ptr会交出控制权,而不是拷贝给新的auto_ptr。

3)常用操作函数:
*原始资源访问:显式访问:get()返回所指对象的地址。隐式访问:operator*和operator->。
*release():放弃auto_ptr原先拥有对象的所有权。
*reset(T *ptr=0):以ptr重新初始化auto_ptr。

(二)shared_ptr:非常有用、非常有价值。
1)概述:shared_ptr包装了new操作符在堆上分配的动态对象,实现的是引用计数型智能指针,可以自由拷贝和赋值,在任意地方共享它,当引用计数为0时它才删除被包含的动态分配的对象。shared_ptr可以安全的放到标准容器中。

2)使用方法:shared_ptr定义在tr1/shared_ptr.h头文件中,使用时需#include<tr1/memory>。shared_ptr在命名空间tr1中定义,使用时需tr1::shared_ptr。

3)常用操作函数:
*原始资源访问:显式访问:get()返回所指对象的地址。隐式访问:operator*和operator->。
*reset(T *ptr=0):将引用计数减1,停止对指针的共享,除非引用计数为0,否则不会发生删除操作。带参数的reset则将原指针引用减1的同时改为管理另一个指针。
*检测引用计数:unique():在shared_ptr是指针唯一的所有者时返回true。use_count():返回当前指针的引用计数。

4)shared_array类似shared_ptr,但是它包装的是new[]操作符在堆上分配的动态数组。


(三)weak_ptrweak_ptr定义在tr1/shared_ptr.h头文件中,使用时需#include<tr1/memory>。

*weak_ptr是为配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手而不是智能指针,因为它不具有普通指针的行为,没有重载operator*和->。最大作用是协助shared_ptr工作,检测资源的使用情况。
*它的构造不会引起指针引用计数的增加,析构也不会导致引用计数的减少。
*weak_ptr没有重载operator*和->,它不共享指针,不能操作资源。


(四)scoped_ptr:类似auto_ptr,但拥有权不能转让。

*scoped_ptr把复制构造函数和赋值操作符都声明为私有的,禁止对智能指针的赋值操作,从而保证被它管理的指针不能被转让所有权。

(五)scoped_array:类似scoped_ptr,但是它包装的是new[]操作符在堆上分配的动态数组。

(六)intrusive_ptr:boost不推荐使用。


原创粉丝点击