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>> 。