处理数组时 make_unique 和 make_shared 之间的差异

Mut*_*key 6 c++ smart-pointers make-shared

从 C++17 开始,您可以使用它make_unique来创建指向数组的智能指针,例如:

unique_ptr<int[]> ptr = make_unique<int[]>(10);
Run Code Online (Sandbox Code Playgroud)

这将创建一个指向 10 个元素的数组的智能指针(事实上,将调用正确的 deleter[] 也很棒)。

然而,根据this make_shared不支持这样的功能(至少在 C++17 中不支持,据我所知):

shared_ptr<int[]> ptr = make_shared<int[]>(10);
Run Code Online (Sandbox Code Playgroud)

上面的代码显然是非法的。事实上,我的 Visual Studio 2017 (v141) 吐出了以下错误:

C2070: 'int[]': illegal sizeof operand'
Run Code Online (Sandbox Code Playgroud)

有趣的是,shared_ptr它本身确实支持数组类型(即shared_ptr<int[]>合法,但make_shared又不支持。然而make_unique确实如此。

问题是,是什么阻止了标准制定者支持make_shared数组类型,就像 的情况一样make_unique

lub*_*bgr 2

是什么阻止了标准制定者让 make_shared 支持数组类型 [...]?

可能没什么,这种情况根本没有被考虑,类似于std::make_uniqueC++11 中不存在但在 C++14 中添加了。正如评论中所指出的,这个缺失的部分将随 C++20 一起提供。

std::unique_ptr不过, 和之间存在差异std::shared_ptr,这使得忽略原始数组指针变得容易:自定义删除器是std::unique_ptr类型的一部分,但不是std::shared_ptr类型的一部分。因此,您可以像这样处理数组

std::shared_ptr<int> array = std::shared_ptr<int>(new int[10],
    [](int *ptr){ delete []ptr; });
Run Code Online (Sandbox Code Playgroud)

因此将正确的内存清理委托给对象创建点。这使得可以轻松地将原始数组视为实例的特殊情况std::shared_ptr

  • @lubgr IIRC 和我在这里看到的所有内容(https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr)向我展示了`shared_ptr&lt;int[]&gt; ptr(new int[10])`在 C++17 中应该可以正常工作。在 C++17 之前,您还可以使用 `std::unique_ptr&lt;int[]&gt; arr(new int[1]); std::shared_ptr&lt;int&gt; ptr(std::move(arr));` (4认同)