shared_array

shared_array类似shared_ptr,它包装了new[]操作符在堆上分配的动态数组,同样使用引用计数机制为动态数组提供了一个代理,可以在程序的生命周期里长期存在,直到没有任何引用后才释放内存。

类摘要

template<class T>
class shared_array {
public:
   explicit shared_array(T * p - 0); //构造函数
   template<class D> shared_array(T * p, D d);
   ~shared_array(); //析构函数
   shared_array(shared_array const & r); //拷贝构造函数
   shared_array & operator=(shared_array const & r); //拷贝赋值
   void reset(T * p = 0); //重置指针
   template<class D> void reset(T* p, D d);
   T & operator[](std::ptrdiff_t i) const() const; //重载操作符[]
   T * get() const; //获得原始指针
   bool unique() const; //是否唯一
   long use_count() const; //引用计数
   void swap(shared_array<T> & b); //交换指针
};

shared_array的接口与功能几乎是与shared_ptr是相同的,主要区别是:
1)构造函数接受的指针p必须是new[]的结果,而不能是new表达式的结果
2)提供 operator[]操作符重载,可以像普通数组一样用下标访问元素
3)没有*、->操作符重载,因为shared_array持有的不是一个普通指针
4)析构函数使用delete[]释放资源,而不是delete。

用法

shared_array就像是shared_ptr和scoped_array的结合体——既具有shared_ptr的优点,也具有scoped_array的缺点。有关shared_ptr和scoped_array的讨论大都适合它,因此这里不再详细讲解,仅给出一个小例子说明:

#include <boost/smart_ptr.hpp>
using namespace boost;

void case1()
{
	int* arr = new int[100]; //一个动态数组
	scoped_array<int> sa(p); //shared_array代理动态数组
	assert(sa.unique()); //唯一持有指针

    shared_array<int> sa2 = sa; //共享数组,引用计数增加
    assert(sa2.use_count() == 2); //引用计数增加
    
	sa[0] = 10; //可以使用operator[]访问元素
	assert(sa2[0] == 10); //离开作用域,自动删除动态数组
}

同样的,在使用shared_array重载的operator[]时要小心,shared_array不提供数组索引的范围检查,如果使用了超过动态数组大小的索引或者是负数索引将引发可怕的未定义行为。

shared_array能力有限,多数情况下它可以用shared_ptr<std::vector>或者std::vector<shared_ptr>来代替,这两个方案具有更好的安全性和更多的灵活性,而所付出的代价几乎可以忽略不计。

代码示例

#include <iostream>
using namespace std;

#include <boost/smart_ptr.hpp>
using namespace boost;

int main()
{
	int* p = new int[100];

	shared_array<int> sa(p);
	assert(sa.unique());

	shared_array<int> sa2 = sa;
	assert(sa2.use_count() == 2);

	sa[0] = 10;
	assert(sa2[0] == 10);
}


Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐