scoped_array与scoped_ptr基本是一对孪生兄弟,它包装了new[]操作符(而不是new)在堆上分配的动态数组,为动态数组提供了一个代理(Proxy),保存正确地释放内存。它弥补了标准库中没有指向数组的智能指针的遗憾。
类摘要:
template<class T> class shared_array { private: // Borland 5.5.1 specific workarounds typedef checked_array_deleter<T> deleter; typedef shared_array<T> this_type; public: typedef T element_type; explicit shared_array(T * p = 0); template<class D> shared_array(T * p, D d); void reset(T * p = 0); template <class D> void reset(T * p, D d); T & operator[] (std::ptrdiff_t i) const; T * get() const; bool unique() const;// never throws long use_count() const; // never throws void swap(shared_array<T> & other);// never throws operator unspecified-bool-type() const; private: T * px; // contained pointer detail::shared_count pn; // reference counter };
scoped_array与scoped_ptr区别基本不大,主要特点如下:
1,构造函数接受的指针p必须是new[]的结果,而不是new表达式的结果;
2,没有*、->操作符重载,scoped_array持有的不是一个普通指针;
3,析构函数使用delete[],而不是delete;
4,提供operator[]重载,可以像普通数组一样使用下标访问元素;
5,没有begin(),end()等类似容器迭代器操作函数。
scoped_array管理的是动态数组,而不是单个动态对象,通常创建方式是的。scoped_array<int> sa(new int[100]); //包装动态数组
既然使用重载了下标操作符那么自然可以这样使用,sa[0] = 10;
但是注意,它不提供指针运算,所以不能用数组首地+N的方式访问数组元素,如*(sa + 10) = 10;错误用法,无法通过编译
scoped_array不提供数组索引的范围检查,如果使用了超过动态数组大小的索引或是负数索引将会引发未定义行为。
使用示例:
#include <iostream> #include <algorithm> #include <boost/smart_ptr.hpp> using namespace boost; using namespace std; int main(){ int *arr = new int[100];//a dynamically allocated array scoped_array<int> sa(arr); // scoped_array object proxied original allocated array 代理原始动态数组 fill_n(&sa[0],100,5);//use stdandard library algorithm,fill the entire array with 5 sa[30] = sa[10] + sa[20];//support operator[] cout << sa[30] << endl; //desturctor,automatically destory resource }
运行结果:
10
注意:sa[30] = sa[10] + sa[20];这句很容易产生误解。scoped_ptr使用示例中的sp2 = sp;是两个对象之间的进行赋值操作,这种行为是被禁止了的。而sa[10],sa[20],sa[30]均不是对象,它们之间的操作只是简单的算术运算,是在一个对象里进行,所以并未涉及对象间的赋值操作,不要混淆了。
使用建议:
scoped_array使用起来很轻便,没有为程序增加额外的负担,它的速度与原始数组一样快,很适合习惯用new操作符在堆上分配内在的同仁,但scoped_array功能有限,不能动态增长,也没有迭代支持,不能搭配STL算法,仅有一个纯粹的数组接口。
需要动态数组的话尽量使用std::vector容器,相比之下它比scoped_array更灵活,而只付出了很小的代价。
vector<int> sa(100,2); sa[30] = sa[10] + sa[20];
很显然,std::vector更简洁,而且有丰富的成员函数来操作数据,易于维护。
除非对性能有非常苛刻的要求,或者编译器不支持标准库(比如某些嵌入式操作系统),否则不推荐使用scoped_array,它只是为了与老式的C风格代码兼容而使用的类,它的出现往往代表你的代码中存在隐患。