std::unique_ptr::reset 检查托管指针无效? [英] std::unique_ptr::reset checks for managed pointer nullity?

查看:45
本文介绍了std::unique_ptr::reset 检查托管指针无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读有关 C++11 智能指针的信息,以便在我的源代码中使用它们,我一直在阅读的文档是 cppreference.com 上的文档;在阅读 std::unique_ptr 时,在 <代码>重置功能有一个文档对我来说似乎不正确(强调我的):

<块引用>

替换托管对象.

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

    1. 保存当前指针的副本old_ptr = current_ptr.
    2. 用参数 current_ptr = ptr 覆盖当前指针.
    3. 如果旧指针不为空,则删除之前管理的对象if(old_ptr != nullptr) get_deleter()(old_ptr).

在 C++ 标准文档中,我们可以看到众所周知的删除空指针特性:

摘自n3690标准5.3.5删除(强调我的):

<块引用>

如果删除表达式的操作数的值不是空指针值,则:

——如果对要删除的对象的 new 表达式的分配调用没有省略,delete-expression 将调用一个释放函数.new 表达式的分配调用返回的值应作为第一个参数传递给释放函数.

否则,delete-expression 将不会调用释放函数.

所以,我想知道为什么 cppreference 说 unique_ptr::reset 函数在删除之前检查托管指针的无效性,即使 te 标准说不会调用任何释放函数一个空指针(这就是为什么 cppreference 文档对我来说似乎不正确).

很明显我一定是弄错了,这样做肯定是有原因的,但我无法想象这可能是什么原因.有什么提示吗?

PS:标准中的何处定义了 std::unique_ptr 必须如何实现或表现?在 20.9.1 类模板 unique_ptr 中,我找不到任何关于 check-for-nullity 的东西.

解决方案

是的,非空检查是标准要求的(C++11,[unique.ptr.single.modifiers]§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 本身可以扩大可以直接使用的删除器的选择范围.

I've been reading about the C++11 smart pointers in order to use them on my sources, the documentation I've been reading is the one on cppreference.com; while reading about the std::unique_ptr, on the reset function there's a documentation that seems incorrect to me (emphasis mine):

Replaces the managed object.

  • Given current_ptr, the pointer that was managed by *this, performs the following actions, in this order:

    1. Saves a copy of the current pointer old_ptr = current_ptr.
    2. Overwrites the current pointer with the argument current_ptr = ptr.
    3. If the old pointer was non-empty, deletes the previously managed object if(old_ptr != nullptr) get_deleter()(old_ptr).

In the C++ standard documentation, we can read the well known delete null pointer feature:

Extract from n3690 standard 5.3.5 Delete (emphasis mine):

If the value of the operand of the delete-expression is not a null pointer value, then:

— If the allocation call for the new-expression for the object to be deleted was not omitted, the delete-expression shall call a deallocation function. The value returned from the allocation call of the new-expression shall be passed as the first argument to the deallocation function.

Otherwise, the delete-expression will not call a deallocation function.

So, I'm wondering why cppreference says that the unique_ptr::reset function checks for the nullity of the managed pointer before it's deletion even while te standard says that no deallocation function would be called over a null pointer (that's why the cppreference documentation seems incorrect to me).

Is kind of obvious that I must be mistaken and there must be a reason to do things this way, but I'm unable to imagine what reason it could be. Any hints?

PS: Where in the standard is defined how the std::unique_ptr must be implemented or behave? In the 20.9.1 Class template unique_ptr I cannot found anything about the check-for-nullity stuff.

解决方案

Yes, the check for non-null is required by the standard (C++11, [unique.ptr.single.modifiers]§4):

void reset(pointer p = pointer()) noexcept;

4 Effects: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not equal to nullptr, calls get_deleter()(old_p). [ Note: The order of these operations is significant because the call to get_deleter() may destroy *this. —end note ]

(emphasis mine)

Discussion: An alternative way to standardise it would be to put the "burden" on the user of the class, i.e. require all deleters (the default one and any custom ones) to work fine when invoked on a null pointer.

However, I understand the idea was to enable functions like free() and even things like a hypothetical unlock_mutex(Mutex*) to work as deleters out-of-the-box, regardless of how/if they handle null pointers. So putting this check into the unique_ptr itself broadens the selection of deleters which can be used directly.

这篇关于std::unique_ptr::reset 检查托管指针无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆