我一直在阅读有关C ++ 11智能指针的内容,以便在我的源代码中使用它们,我一直在阅读的文档是cppreference.com上的文档;在阅读有关std::unique_ptr
的{{1}}时,reset
function上的文档对我来说似乎不正确(强调我的):
替换托管对象。
鉴于
current_ptr
,由*this
管理的指针按以下顺序执行以下操作:
- 保存当前指针
old_ptr = current_ptr
的副本。- 使用参数
current_ptr = ptr
覆盖当前指针。- 如果旧指针非空,则删除以前管理的对象
if(old_ptr != nullptr) get_deleter()(old_ptr)
。
在C ++标准文档中,我们可以阅读众所周知的删除空指针功能:
摘自n3690
标准 5.3.5删除(强调我的):
如果 delete-expression 的操作数值不是空指针值,则:
- 如果没有省略要删除的对象的new-expression的分配调用, delete-expression 将调用释放函数。从new-expression的分配调用返回的值应作为第一个参数传递给deallocation函数。
- 否则, delete-expression 将不会调用释放函数。
所以,我想知道为什么cppreference说unique_ptr::reset
函数在删除之前检查托管指针的无效性,即使te标准表示不会通过空指针调用解除分配函数(这就是为什么cppreference文档对我来说似乎不正确。)
PS:标准中定义了std::unique_ptr
必须如何实施或表现的位置?在 20.9.1类模板unique_ptr
中,我找不到任何关于 check-for-nullity 的内容。
答案 0 :(得分:6)
是的,标准要求检查非null(C ++ 11,[unique.ptr.single.modifiers]§4
):
void reset(pointer p = pointer()) noexcept;
4效果:将
p
分配给存储的指针,然后如果存储的指针old_p
的旧值不等于{{ 1}},调用nullptr
。 [注意:这些操作的顺序很重要,因为调用get_deleter()可能会破坏get_deleter()(old_p)
。 -end note ]
(强调我的)
讨论:标准化它的另一种方法是将“负担”放在类的用户身上,即需要所有删除者(默认的和任何删除者)自定义的)在空指针上调用时工作正常。
但是,我理解这个想法是启用像*this
这样的函数,甚至像假设的free()
这样的函数也可以作为开箱即用的删除函数,无论它们如何处理null指针。因此,将此检查放入unlock_mutex(Mutex*)
本身会扩大可直接使用的删除选择。
答案 1 :(得分:2)
如果您的删除程序没有执行简单的删除操作,该怎么办?如果您的unique_ptr有自定义删除器执行其他操作,您是否希望使用nullptr作为参数调用删除器? :d