0.阅读
1.初识scoped_array
scoped_array很像scoped_ptr,它包装了new[]操作符(不是单纯的new)在堆上分配的动态数组,为动态数组提供了一个代理,保证可以正确地释放内存. scoped_array相当于C++11标准中管理数组对象用法的unique_ptr.
2.类摘要
template<class T>
class scoped_array
{
public:
explicit scoped_array(T* p = 0);
~scoped_array();
void reset(T* p =0);
T& operator[](std::ptrdiff_t i)const;
T* get() const;
// operator unspecified_bool_type() const; // 这个有空的时候看一下
void swap(scoped_array& b);
};
scoped_array的接口和功能几乎是与scoped_ptr是相同的(甚至还要少一些),主要特点如下:
(1)构造函数接受的指针p必须是new[ ]的结果,而不能是new表达式的结果;
(2)没有* ,->操作符重载,因为scoped_array持有的不是一个普通指针;
(3)析构函数使用delete[]释放资源,而不是delete;
(4)提供operator[]操作符重载,可以像普通数组一样用下标访问元素;
(5)没有begin(),end()等类似容器的迭代器操作函数.
3.用法
scoped_array与scoped_ptr源于相同的设计思想,故而用法非常相似:
它只能在被声明的作用域内使用,不能拷贝、赋值。唯一不同的是scoped_array包装的是new[]
产生的指针,并在析构时调用delete[],因为它管理的是动态数组,而不是单个动态对象.
通常scoped array的创建方式是这样的:
scoped_array<int> sa (new int[100]);// 包装动态数组
scoped_array重载了operator[],因此它用起来就像是一个普通的数组,但因为它不提供指针运
算,所以不能用“数组首地址+N”的方式访问数组元素:
sa[0]=10; // 正确用法,使用operator[]
*(sa+1)=20; // 错误用法,不能通过编译
在使用重载的operator[]时要小心,scoped_array不提供数组索引的范围检查,如果使用了超过动
态数组大小的索引或者是负数索引将引发未定义行为.
下面的代码进一步示范了scoped_array的用法:
#include <boost/smart_ptr.hpp>
using namespace boost;
using namespace std;
int main()
{
int *arr = new int[100]; // 一个整数的动态数组
scoped_array<int> sa(arr); // scoped_array对象代理原始动态数组
fill_n(&sa[0],100,5); // 使用标准库算法赋值数据
sa[10] = sa[20] + sa[30]; // 用起来就像是一个普通数组
} // 这里scoped_array被自析构,释放动态数组资源
4.使用建议
scoped_array没有给程序增加额外的负担,用起来很方便轻巧。它的速度与原始数组同样快,很适
合那些习惯于用new操作符在堆上分配内存的程序员。但scoped_array的功能很有限,不能动态增长,
也没有迭代器支持,不能搭配sTr算法,仅有一个纯粹的“裸”数组接口。而且,我们应当尽量避免使用
new[]操作符,它比new更可怕,是许多错误的来源,因为:
int *p = new int[10];
delete p;
这样的代码完全可以通过编译,无论是编译器还是程序员都很难区分出new[]和new分配的空间,而错
误地运用delete将导致资源异常.
在需要动态数组的情况下我们应该使用std::vector,它比scoped_array提供了更多的灵活性,而只
付出了很小的代价。使用std::vector,之前的例子可以写成:
vector<int> sa(100,5);
sa[10]=sa[20]+sa[30];
很明显,std::vector只用一条语句就完成了scoped_array三条语句的初始化和赋值工作.
因为vector有丰富的成员函数来操纵数据,能够使代码更加简单明了,易于维护.
除非对性能有非常苛刻的要求,或者编译器不支持标准库(比如某些嵌入式操作系统),否则本书不推荐使用scoped_array,它只是为了与老式C风格代码兼容而使用的类,它的出现往往意味着你的代码中存在着隐患.
5.说明
本文取自《BOOST程序库完全开发指南:深入C++“准”标准库第3版.