智能指针作为条件:if (p) 和 if (i.get()) 是不是等效?

Posted

技术标签:

【中文标题】智能指针作为条件:if (p) 和 if (i.get()) 是不是等效?【英文标题】:Smart pointer as condition: are if (p) and if (p.get()) equilavent?智能指针作为条件:if (p) 和 if (i.get()) 是否等效? 【发布时间】:2016-10-17 13:41:50 【问题描述】:

p 成为共享/唯一指针。 if (p)if (p.get()) 是否等效?

如果不是,在哪些情况下这些条件或条件中的代码会有不同的行为?

从cppreference 我读到std::shared_ptr::operator bool 检查是否get() != nullptr。这是operator bool的确切实现吗?

【问题讨论】:

你不相信cppreference吗? @NathanOliver 我一般都是这样!只是想确定一下,因为我的共享指针是在多线程环境中使用的。 为什么多线程环境有什么不同? @Slava 好问题 - 我想我还没有完全想通为什么会这样。我想我担心if 中的底层对象会被删除。但无论哪种方式,p 都将在 if 条件范围内,保持引用计数(如果 p 当然是有效指针) 如果您在共享 shared_ptr 上有竞争条件 - if(p.get()) 不会让它变得更好,恕我直言,它会让它变得更糟。 std::atomic 专门用于 std::shared_ptr,或者您应该使用互斥锁。 【参考方案1】:

“确切的实现”不应该是您关心的问题(它会因编译器而异,因版本而异,并且可能取决于您提供给编译器的选项)

您关心的应该是“符合标准的编译器的行为方式”,答案是“是的,if(ptr) 应该始终产生与if(ptr.get()) 相同的结果

来自标准:

算术、无作用域枚举、指针或指向成员类型的指针的纯右值可以转换为 bool 类型的纯右值。将零值、空指针值或空成员指针值转换为 false;任何其他值都转换为 true 。 std::nullptr_t 类型的纯右值可以转换为 bool 类型的纯右值;结果是假的。

智能指针算作nullable pointers,具有以下要求:

P 类型的对象 p 可以根据上下文转换为 bool(子句 [conv])。效果应该就像 p != nullptr 代替 p 被求值一样。

(感谢 T.C. 的引用)

【讨论】:

从技术上讲,这个引用是不够的,因为unique_ptr 支持花哨的指针,而它的pointer 不一定是内置指针。但是,NullablePointer 要求涵盖了这一点。 同意,但我找不到涵盖“智能指针”可能性的简洁报价。不过,据我所知,所有标准和增强型智能指针的行为方式都符合您的预期——我试图提出的观点 [花费您的精力担心其他事情并相信编译器会正确处理 [除非您是多线程(后来添加到 cmets 中),在这种情况下不要指望编译器能读懂你的想法]] [unique.ptr.single]/3,与[nullablepointer.requirements]/3结合使用。【参考方案2】:

operator bool() 对智能指针背后的目的是使智能指针在执行有效性检查的常见情况下表现得像常规指针一样,即在您编写的情况下

if (myPointer) 
    ... // Do something

具体的实现可能不同。除了调用get() 并将结果与​​nullptr 进行比较之外,一个符合标准的实现可以,例如,检查一个存储get() 返回值的成员变量,或者检查一个指示指针未指向的私有标志任何有效的东西。

然而,对于程序员而言,只要知道当get() 返回一个非空值时该实现将返回true,并且当get() 返回时它也将返回false,就足够了nullptr.

【讨论】:

【参考方案3】:

if (p)(p.get()) 是否等效?

来自this reference(同样适用于unique_ptr):

检查*this 是否存储了非空指针,即是否get() != nullptr

是的,if (p)if (p.get()) 具有相同的行为。不,从迂腐的角度来说,它们并不完全等价:前者有一个函数调用,后者有一个不同的函数调用和一个指针比较。实际上,两者都可能生成相同的代码。

如果不是,这些条件或条件中的代码在什么情况下会有不同的行为?

它们的行为完全相同。

这是 operator bool 的确切实现吗?

这正是实现的行为方式。

确切的实现是……定义的实现。您可以阅读您的标准库实现的源代码以找出答案。

【讨论】:

【参考方案4】:

它们的行为完全相同。

为了找出我们可以使用指针空检查的各种方式,您可以查看以下内容

http://www.artima.com/cppsource/safebool.html

这被称为安全布尔成语。尽管它在 c++11 中似乎已经过时,但它很好地展示了在 sharedPtrs 上使用 bool 操作。

【讨论】:

以上是关于智能指针作为条件:if (p) 和 if (i.get()) 是不是等效?的主要内容,如果未能解决你的问题,请参考以下文章

C语言:if(条件) 条件是一个指针变量,它啥时候为真?

c语言中的if和指针

指针能作为引用参数吗?

智能指针实现

Shell脚本的条件测试和if条件语句使用

在条件或循环中分配智能指针