我一直在阅读C 11智能指针,以便在我的源代码中使用它们,我一直在阅读的留档是cppreference.com上的留档;在阅读std::unique_ptr
时,在重置
函数上有一个留档对我来说似乎不正确(强调我的):
替换托管对象。
>
给定current_ptr
,由*this
管理的指针按以下顺序执行以下操作:
old_ptr=current_ptr
.覆盖当前指针current_ptr=ptr
。if(old_ptr!=nullptr)get_deleter(old_ptr)
。在C标准留档中,我们可以读到众所周知的删除空指针特性:
摘自n3690
标准5.3.5删除(强调我的):
如果删除表达式的操作数的值不是空指针值,则:
-如果要删除的对象的new表达式的分配调用没有被省略,则delete-表达式应调用释放函数。new-表达式的分配调用返回的值应作为第一个参数传递给释放函数。
-否则,删除表达式将不会调用释放函数。
所以,我想知道为什么cpprevery说unique_ptr::重置
函数在删除之前检查托管指针的无效性,即使te标准说不会在空指针上调用释放函数(这就是为什么cp留首选档对我来说似乎不正确)。
很明显,我一定是搞错了,这样做一定有原因,但我无法想象这可能是什么原因。有线索吗?
PS:在标准中定义了std::unique_ptr
必须如何实现或行为?在20.9.1 Class模板unique_ptr
中,我找不到任何关于检查无效的东西。
是的,标准需要检查非空(C 11,[唯一. ptr.single.修饰符]§4
):
void reset(pointer p = pointer()) noexcept;
4效果:将p
赋值给存储的指针,然后如果存储指针的旧值old_p
不等于nullptr
,则调用get_deleter()(old_p)
。[注意:这些操作的顺序很重要,因为对get_deleter()的调用可能会破坏*this
。-结束注释]
(强调我的)
讨论:标准化它的另一种方法是将“负担”放在类的用户身上,即要求所有删除器(默认删除器和任何自定义删除器)在空指针上调用时工作正常。
然而,我理解这个想法是为了使像free()
这样的函数,甚至像假设的unlock_mutex(Mutex*)
这样的函数能够作为开箱即用的删除器工作,而不管它们如何/是否处理空指针。因此,将此检查放入unique_ptr
本身拓宽了可以直接使用的删除器的选择范围。
如果你的删除器不做简单的删除操作怎么办?如果你的unique_ptr有一个自定义的删除器做其他事情怎么办,你希望你的删除器被调用nullptr作为参数吗?: D