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。 当TU[N]Y(*)[N]可转换为T* ; 当TU[]Y(*)[]可转换为T* ; 否则, Y*应转换为T*

您可以使用的一个可能更简单的select是shared_ptr<vector<int>>