std::shared_ptr
指向一个数组吗?例如,
std::shared_ptr<int> sp(new int[10]);
如果没有,那为什么不呢?我已经知道的原因之一是无法增加/减少
std::shared_ptr
。因此它不能像普通的数组指针一样使用。
使用 C++17,
shared_ptr
可用于管理动态分配的数组。在这种情况下,shared_ptr
模板参数必须是T[N]
或T[]
。所以你可以写
shared_ptr<int[]> sp(new int[10]);
来自 n4659,[util.smartptr.shared.const]
template<class Y> explicit shared_ptr(Y* p);
要求:
必须是完整类型。表达式Y
(当delete[] p
是数组类型时)或T
(当delete p
不是数组类型时)应具有明确定义的行为,并且不应引发异常。T
...
备注: 当为数组类型时,此构造函数不应参与重载决策,除非表达式T
格式良好且delete[] p
为T
且U[N]
可转换为Y(*)[N]
,或者T*
是T
和U[]
可转换为Y(*)[]
。 ...T*
element_type
现在定义为
using element_type = remove_extent_t<T>;
operator[]
访问数组元素
element_type& operator[](ptrdiff_t i) const;
需要:
。如果get() != 0 && i >= 0
是T
,则U[N]
。 ...i < N
备注: 当不是数组类型时,未指定是否声明该成员函数。如果声明了它,则未指定其返回类型是什么,但函数的声明(尽管不一定是定义)应格式良好。T
在 C++17 之前,
shared_ptr
不能 用于管理动态分配的数组。默认情况下,当不再有对托管对象的引用时,shared_ptr
将在托管对象上调用
delete
。但是,当您使用
new[]
分配时,您需要调用
delete[]
而不是
delete
来释放资源。为了正确使用
shared_ptr
与数组,您必须提供自定义删除器。
template< typename T >
struct array_deleter
{
void operator ()( T const * p)
{
delete[] p;
}
};
创建shared_ptr如下:
std::shared_ptr<int> sp(new int[10], array_deleter<int>());
现在
shared_ptr
将在销毁托管对象时正确调用
delete[]
。上面的自定义删除器可能会被替换为
std::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());
std::shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });
unique_ptr
更适合此任务,因为它对数组类型有部分专门化。
std::unique_ptr<int[]> up(new int[10]); // this will correctly call delete[]
库基础技术规范 提供的,它增强了 shared_ptr
,使其能够在拥有对象数组的情况下开箱即用。该 TS 的
shared_ptr
更改的当前草案可以在N4082 中找到。这些更改可以通过
std::experimental
命名空间访问,并包含在
<experimental/memory>
标头中。支持数组
shared_ptr
的一些相关更改包括:— 成员类型的定义
element_type
发生变化
— 正在添加会员typedef T 元素类型;
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]>
都有效,并且都会导致在托管对象数组上调用
delete[]
。
template<class Y> explicit shared_ptr(Y* p);
要求:
Y
应为完整类型。表达式delete[] p
(当T
是数组类型时)或delete p
(当T
不是数组类型时)应格式良好,应具有明确定义的行为,并且不应引发异常。当T
为U[N]
时,Y(*)[N]
可转换为T*
;当T
为U[]
时,Y(*)[]
可转换为T*
;否则,Y*
应可转换为T*
。
shared_ptr<vector<int>>
。