std :: unique_ptr :: reset检查托管指针的无效性?

时间:2014-02-06 14:48:36

标签: c++ c++11 language-lawyer unique-ptr delete-operator

我一直在阅读有关C ++ 11智能指针的内容,以便在我的源代码中使用它们,我一直在阅读的文档是cppreference.com上的文档;在阅读有关std::unique_ptr的{​​{1}}时,reset function上的文档对我来说似乎不正确(强调我的):

  

替换托管对象。

     
      
  • 鉴于current_ptr,由*this管理的指针按以下顺序执行以下操作:

         
        
    1. 保存当前指针old_ptr = current_ptr的副本。
    2.   
    3. 使用参数current_ptr = ptr覆盖当前指针。
    4.   
    5. 如果旧指针非空,则删除以前管理的对象if(old_ptr != nullptr) get_deleter()(old_ptr)
    6.   
  •   

在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 的内容。

2 个答案:

答案 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