make_unique 和 make_shared 处理数组时的区别
differences between make_unique and make_shared when handling arrays
从 C++17 开始,您可以使用 make_unique
来创建指向数组的智能指针,例如:
unique_ptr<int[]> ptr = make_unique<int[]>(10);
这将创建一个指向包含 10 个元素的数组的智能指针(将调用适当的 deleter[] 的事实也很棒)。
但是根据 this make_shared
不支持这样的功能(至少在 C++17 中不支持,据我所知):
shared_ptr<int[]> ptr = make_shared<int[]>(10);
上面的代码显然是非法的。事实上,我的 Visual Studio 2017 (v141) 吐出以下错误:
C2070: 'int[]': illegal sizeof operand'
有趣的是shared_ptr
本身确实支持数组类型(即shared_ptr<int[]>
是legal),但make_shared
不支持。而 make_unique
会。
问题是,是什么阻止了标准制定者让 make_shared
支持数组类型,就像 make_unique
的情况一样?
What prevented the standard maker people to let make_shared support array types [...]?
可能什么都没有,这种情况根本没有考虑,类似于 std::make_unique
不存在于 C++11 中但添加到 C++14 中。正如评论中指出的那样,这个缺失的部分将随 C++20 一起提供。
std::unique_ptr
和 std::shared_ptr
之间的区别使得忽略原始数组指针变得容易,但是:自定义删除器是 std::unique_ptr
类型的一部分但不是 [= 的一部分13=]的类型。因此,你可以像这样处理一个数组
std::shared_ptr<int> array = std::shared_ptr<int>(new int[10],
[](int *ptr){ delete []ptr; });
因此将正确的内存清理委托给对象创建点。这使得将原始数组视为 std::shared_ptr
个实例的特例变得容易。
从 C++17 开始,您可以使用 make_unique
来创建指向数组的智能指针,例如:
unique_ptr<int[]> ptr = make_unique<int[]>(10);
这将创建一个指向包含 10 个元素的数组的智能指针(将调用适当的 deleter[] 的事实也很棒)。
但是根据 this make_shared
不支持这样的功能(至少在 C++17 中不支持,据我所知):
shared_ptr<int[]> ptr = make_shared<int[]>(10);
上面的代码显然是非法的。事实上,我的 Visual Studio 2017 (v141) 吐出以下错误:
C2070: 'int[]': illegal sizeof operand'
有趣的是shared_ptr
本身确实支持数组类型(即shared_ptr<int[]>
是legal),但make_shared
不支持。而 make_unique
会。
问题是,是什么阻止了标准制定者让 make_shared
支持数组类型,就像 make_unique
的情况一样?
What prevented the standard maker people to let make_shared support array types [...]?
可能什么都没有,这种情况根本没有考虑,类似于 std::make_unique
不存在于 C++11 中但添加到 C++14 中。正如评论中指出的那样,这个缺失的部分将随 C++20 一起提供。
std::unique_ptr
和 std::shared_ptr
之间的区别使得忽略原始数组指针变得容易,但是:自定义删除器是 std::unique_ptr
类型的一部分但不是 [= 的一部分13=]的类型。因此,你可以像这样处理一个数组
std::shared_ptr<int> array = std::shared_ptr<int>(new int[10],
[](int *ptr){ delete []ptr; });
因此将正确的内存清理委托给对象创建点。这使得将原始数组视为 std::shared_ptr
个实例的特例变得容易。