std::shared_ptr
指向一个数组吗?例如,std::shared_ptr<int> sp(new int[10]);
如果不行,那为什么呢?我已经意识到的一个原因是无法对std::shared_ptr进行递增/递减操作。因此,它不能像普通指向数组的指针一样使用。
std::shared_ptr
指向一个数组吗?例如,std::shared_ptr<int> sp(new int[10]);
在 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);
Requires:
Y
shall be a complete type. The expressiondelete[] p
, whenT
is an array type, ordelete p
, whenT
is not an array type, shall have well-defined behavior, and shall not throw exceptions.
...
Remarks: WhenT
is an array type, this constructor shall not participate in overload resolution unless the expressiondelete[] p
is well-formed and eitherT
isU[N]
andY(*)[N]
is convertible toT*
, orT
isU[]
andY(*)[]
is convertible toT*
. ...
element_type
现在被定义为:using element_type = remove_extent_t<T>;
可以使用operator[]
来访问数组元素。
在C++17之前,不能使用
element_type& operator[](ptrdiff_t i) const;
Requires:
get() != 0 && i >= 0
. IfT
isU[N]
,i < N
. ...
Remarks: WhenT
is not an array type, it is unspecified whether this member function is declared. If it is declared, it is unspecified what its return type is, except that the declaration (although not necessarily the definition) of the function shall be well formed.
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[]
。the std::default_delete
partial specialization for array types
std::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());
a lambda expression
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[]
C++17 之前另一种解决方法是由库基础技术规范提供的,这个规范增强了 shared_ptr
以使其可以直接管理对象数组。目前计划在该技术规范中更改 shared_ptr
的草案可以在N4082中找到。这些更改将通过 std::experimental
命名空间访问,并包含在 <experimental/memory>
头文件中。支持 shared_ptr
对数组的一些相关更改包括:
— 成员类型 element_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]>
都是有效的,且都会导致在被管理的对象数组上调用delete[]
。
template<class Y> explicit shared_ptr(Y* p);
Requires:
Y
shall be a complete type. The expressiondelete[] p
, whenT
is an array type, ordelete p
, whenT
is not an array type, shall be well-formed, shall have well defined behavior, and shall not throw exceptions. WhenT
isU[N]
,Y(*)[N]
shall be convertible toT*
; whenT
isU[]
,Y(*)[]
shall be convertible toT*
; otherwise,Y*
shall be convertible toT*
.
shared-array
(http://www.boost.org/doc/libs/1_51_0/libs/smart_ptr/shared_array.htm). - jogojapanstd::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());
这行代码使用了 C++11 中的智能指针 std::shared_ptr
来管理一个长度为 10 的整型数组。其中 std::default_delete<int[]>()
是删除器,它告诉 shared_ptr
在不需要这个指针时该如何释放内存。注意,new int[10]
分配的是动态内存,因此必须使用 delete[]
操作符来释放它,而 std::default_delete<int[]>
就会把它作为参数传递给 delete[]
操作符。 - yohjpstd::shared_ptr<std::array<int,N>>
应该就足够了。 - Praetorianunique_ptr
有那个偏特化而 shared_ptr
没有? - Adam你可以使用一个可能更容易的替代方案,即 shared_ptr<vector<int>>
。
shared_ptr<array<int, 6>>
。 - Timmmm
std::vector
。您必须小心地使用引用来传递数组,以便不会复制它。访问数据的语法比shared_ptr
更清晰,并且调整大小非常容易。如果您需要STL的所有好处,那么您就可以得到它们。 - Nicu Stiurcastd::array
。它与原始数组几乎相同,但具有适用于大多数库组件的正确语义。特别是该类型的对象使用delete
而不是delete[]
销毁。而且,与vector
不同,它直接将数据存储在对象中,因此不会额外分配内存。 - celtschk