gpt4 book ai didi

c++ - shared_ptr 到数组 : should it be used?

转载 作者:IT老高 更新时间:2023-10-28 11:30:33 26 4
gpt4 key购买 nike

只是一个关于 shared_ptr 的小查询.

使用 shared_ptr 指向数组是一种好习惯吗?例如,

shared_ptr<int> sp(new int[10]);

如果不是,那为什么不呢?我已经知道的一个原因是不能增加/减少 shared_ptr。因此它不能像普通的指向数组的指针一样使用。

最佳答案

使用 C++17shared_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 expression delete[] p, when T is an array type, or delete p, when T is not an array type, shall have well-defined behavior, and shall not throw exceptions.
...
Remarks: When T is an array type, this constructor shall not participate in overload resolution unless the expression delete[] p is well-formed and either T is U[N] and Y(*)[N] is convertible to T*, or T is U[] and Y(*)[] is convertible to T*. ...

为了支持这一点,成员类型 element_type 现在定义为

using element_type = remove_extent_t<T>;

可以使用 operator[] 访问数组元素

  element_type& operator[](ptrdiff_t i) const;

Requires: get() != 0 && i >= 0. If T is U[N], i < N. ...
Remarks: When T 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.


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::default_delete 数组类型的部分特化

    std::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());
  • 一个 lambda 表达式

    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++ Extensions for Library Fundamentals 引入的变化

Library Fundamentals Technical Specification 提供了上面列出的另一个 C++17 之前的替代方案。 , 增加了 shared_ptr允许它在拥有对象数组的情况下开箱即用。 shared_ptr 的当前草案可以在 N4082 中找到此 TS 的计划更改。 .可通过 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 expression delete[] p, when T is an array type, or delete p, when T is not an array type, shall be well-formed, shall have well defined behavior, and shall not throw exceptions. When T is U[N], Y(*)[N] shall be convertible to T*; when T is U[], Y(*)[] shall be convertible to T*; otherwise, Y* shall be convertible to T*.

关于c++ - shared_ptr 到数组 : should it be used?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13061979/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com