Igo*_*r G 1 c++ language-design shared-ptr c++17
C++ 标准提供了一个别名构造函数shared_ptr:
template <typename T>\nclass shared_ptr\n{\n template <typename U>\n shared_ptr(const shared_ptr<U>& r, element_type* ptr);\n};\nRun Code Online (Sandbox Code Playgroud)\n这样的构造函数意味着一个shared_ptr对象可以以一种方式创建,它拥有一个对象,与 所拥有的相同r,同时存储指向另一个对象的指针 - ptr。
此外,标准明确允许使用此构造函数创建一个shared_ptr不拥有任何东西的对象(从而满足“空”的定义),但仍然指向某个对象(因此被限定为“非空”) :
\n\n[util.smartptr.shared.const]:
\n
\n17。[注2:此构造函数允许使用非空存储指针创建空的shared_\xc2\xadptr 实例。\xe2\x80\x94 尾注]
构造一个空但非空的shared_ptr实例很容易被禁止,例如要求尝试构造shared_ptr具有非空存储指针的空实例应该抛出异常。
但标准选择允许它。我想知道为什么以及为什么。
\n空但非 null 的预期和规范使用场景是什么shared_ptr?
std::shared_ptr别名构造函数是在标准化过程中添加到N2351“Improving shared_ptr for C++0x, Revision 2”中的:
shared_ptr此功能以向后兼容的方式扩展了接口,增加了其表达能力,因此强烈建议将其添加到 C++0x 标准中。它不会引入源代码和二进制兼容性问题。
此时已经注意到:
[注意:此构造函数允许使用非 NULL 存储指针创建空实例。 ——注释结束。]
shared_ptr
别名构造函数同时添加到boost::shared_ptr,充当测试台:https://github.com/boostorg/smart_ptr/commit/54e12d03fdfec63b4d8ff41991c4e64af6b1b4b4 https://github.com/boostorg/smart_ptr/commit/ce72827dc73ac652ed07002b75f32e01 71119c09
至于为什么允许这样做:有一个明确的替代方案,即用户shared_ptr从现有指针和无操作删除器构造 a :
auto sp = shared_ptr(p, [](auto){})
Run Code Online (Sandbox Code Playgroud)
然而,这比别名空状态效率低(因为必须分配单独的控制块)并且表达能力较差,因为不可能确定删除器是无操作。所以没有理由禁止前者。