shared_ptr到一个数组:应该使用它?
只是一个关于shared_ptr
的小查询。
使用shared_ptr
指向数组是否是一个好习惯? 例如,
shared_ptr<int> sp(new int[10]);
如果没有,那为什么不呢? 我已经知道的一个原因是不能递增/递减shared_ptr
。 因此,它不能像正常的数组指针一样使用。
默认情况下, shared_ptr
将在没有更多引用保留的情况下调用pipe理对象的delete
。 但是,当您使用new[]
分配时,您需要调用delete[]
,而不是delete
,以释放资源。
为了正确使用shared_ptr
和数组,你必须提供一个定制的删除器。
template< typename T > struct array_deleter { void operator ()( T const * p) { delete[] p; } };
按如下所示创buildshared_ptr:
std::shared_ptr<int> sp( new int[10], array_deleter<int>() );
现在shared_ptr
将在销毁托pipe对象时正确调用delete[]
。
如注释中所示,在C ++ 11中,可以使用std::default_delete
部分专用化数组types而不是上面的array_deleter
。
std::shared_ptr<int> sp( new int[10], std::default_delete<int[]>() );
您也可以使用lambdaexpression式而不是函子。
std::shared_ptr<int> sp( new int[10], []( int *p ) { delete[] p; } );
另外,除非实际需要共享托pipe对象,否则unique_ptr
更适合执行此任务,因为它具有数组types的部分专用性。
std::unique_ptr<int[]> up( new int[10] ); // this will correctly call delete[]
C ++扩展为图书馆基础引入的变化
shared_ptr
由图书馆基础技术规范(TS)进行扩充,允许它在拥有一系列对象的情况下开箱即用; 将不需要明确提供删除者。 在N4082中可以find当前TS的shared_ptr
变更草案。 这些更改将通过std::experimental
命名空间访问,并包含在<experimental/memory>
头文件中。 一些支持数组的shared_ptr
的相关更改是:
– 成员typeselement_type
的定义发生变化
typedef T element_type;typedef typename remove_extent<T>::type element_type;
– 会员operator[]
正在被添加
element_type& operator[](ptrdiff_t i) const noexcept;
– 与数组的unique_ptr
部分特化不同, shared_ptr<T[]>
和shared_ptr<T[N]>
都是有效的,都会导致在被pipe理的对象数组上调用delete[]
。
template<class Y> explicit shared_ptr(Y* p);
要求 :
Y
应该是一个完整的types。 当T
是数组types时,expression式delete[] p
,或者当T
不是数组types时,delete p
应该是格式良好的,应该有明确定义的行为,并且不会抛出exception。 当T
是U[N]
,Y(*)[N]
可转换为T*
; 当T
为U[]
,Y(*)[]
可转换为T*
; 否则,Y*
应转换为T*
。
您可以使用的一个可能更简单的select是shared_ptr<vector<int>>
。