头文件
#include <memory>
std::shared_ptr (C++11)
模板类定义
template <class T> class shared_ptr;
类说明
共享指针。管理一个保存指针的内存区域,提供有限的垃圾回收机制,可能会在多个对象之间共享该管理权。
shared_ptr类型的对象可以取得一个指针的所有权,并且可以分享该所有权:一旦他们取得了一个指针的所有权,那么当该指针的这一组所有者中最后一个释放所有权的需要负责释放该指针。
shared_ptr对象在他们被销毁的同时释放对指针的所有权,或者是通过赋值操作或者调用 shared_ptr::reset函数来改变shared_ptr对象的值的同时释放所有权。一旦所有共享指针所有权的shared_ptr对象都释放了所有权,被监管的对象就会被删除(通常是调用::delete,但是也可以在构造函数中制定一个不同的删除方法)
shared_ptr对象只能通过复制其值来共享所有权:如果两个shared_ptr对象是从同一个(非共享的)指针构造(或生成)的,则它们都将拥有该指针的所有权而不共享它的所有权,当其中一个释放指针(删除其托管对象)会使另一个shared_ptr对象指向无效位置,这样会导致潜在的访问问题。(这里主要是说共享一份所有权和分别拥有所有权的不同,构造出来的每个shared_ptr对象都有所有权,所有权相当于有多个;使用复制只是共享一份所有权)
另外,shared_ptr对象可以在指向另一个对象的同时共享另一个指针的所有权。这个功能被称作别名(参见构造函数),通常用在已经拥有一个对象所有权,然后用指针指向该对象的成员对象。因此一个shared_ptr可能有两个相关的指针:
- 一个存储的指针,即它所指向的指针,可以使用运算符*进行解引用访问其中的内容。
- 一个拥有的指针(可能是共享的),是拥有所有权的群组在某时刻需要负责释放的指针,它也被当做计数器用。
通常,这两个指针指向同一个对象,但是别名版本的shared_ptr对象(使用alias构造函数构造的对象或者这种对象的拷贝)可能会指向不同的对象。
一个shared_ptr如果不拥有任何指针的所有权称为empty shared_ptr。如果shared_ptr不指向任何对象(存储指针是空)称为null shared_ptr,并且不能够解引用。请注意,empty shared_ptr不一定是null shared_ptr,null shared_ptr也不一定是empty shared_ptr。
shared_ptr对象通过运算符*和->可以实现访问所指向的对象,从而复制了有限的指针功能。出于安全原因,它们不支持指针运算。
一个相关的类weak_ptr可以与shared_ptr对象共享指针而不必拥有它们。
模板参数
T:托管对象的类型,别名为成员类型element_type。
成员类型
下面是shared_ptr成员类型的别名。
成员函数
构造函数
函数原型
根据使用的函数签名构建一个shared_ptr对象:
默认构造函数(1)和(2)
构造一个empty对象(注意不是null,不拥有任何指针,计数为0)
使用指针构造(3)
构造的对象拥有p的所有权,使用计数设置为1。
使用指针+删除器deleter构造(4)
与(3)相同,但对象也拥有deleter del的所有权(如果在某个时刻需要删除p,则使用它来完成)。
使用指针+删除器+分配器allocator构造(5)
与(4)相同,但是内部所需的所有内存都使用alloc来申请(只保留alloc的副本,不拥有其所有权)。
拷贝构造函数(6)
如果X不为空的话,构造的对象会分享X管理目标的所有权, 使用计数加1。
如果X为空的话,则会构造一个empty对象(就像默认构造函数)。
从weak_ptr拷贝构造(7)
与(6)相同,只是如果X管理的指针已经无效的话会抛出bad_weak_ptr的异常。
移动构造函数(8)
新的对象将获取由x管理的内容,包括它拥有的指针。x变成一个空对象(就像默认构造函数构造出来的一样)。
使用其他类型的托管指针移动构造(9)
新创建的对象获取由x管理的内容并将使用计数设置为1。转让指针所有权的对象变为空,自动失去指针的所有权。
别名构造函数(10)
除存储的指针为p外,与(6)相同。该对象不拥有p,并且将不管理其存储。 相反,它共同拥有x的托管对象,并算作x的另一种用法。 它还会在释放时删除x的指针(而不是p)。它可以用来指向已经被管理的对象的成员。(也就是说新创建的对象等同于X)
参数
p: 要被新对象接管其所有权的指针。此指针值不应已由任何其他托管指针管理(即,此值不应使用其他托管指针的get函数的返回值)。U应隐式转换为T(其中T是shared_ptr模板参数)。
del: 用于释放所属对象的Deleter对象。这应该是一个可调用的对象,将指向T的指针作为函数调用的参数(其中T是shared_ptr的模板参数)。
alloc: 用于分配/释放内部存储的分配器对象。