在std :: shared_ptr中检查null

Nos*_*mus 35 c++ shared-ptr

我在想,如果我需要检查是否spnull之前我用它.纠正我,如果我错了,但创建一个别名不会增加ref计数器,因此通过进入方法我们正在使用共享指针,我们不知道嵌入式指针是否已被重置..我是正确的假设这个?

Class::MyFunction(std::shared_ptr<foo> &sp)
{    
    ...  
    sp->do_something();  
    ...  
}
Run Code Online (Sandbox Code Playgroud)

Sho*_*hoe 47

你必须考虑到std::shared_ptr整体仍然是一个指针(封装在像类这样的指针中)并且它确实可以在内部构造nullptr.当发生这种情况时,表达式如:

ptr->
*ptr
Run Code Online (Sandbox Code Playgroud)

导致未定义的行为.所以,是的,如果你期望指针也是nullptr,那么你应该检查它的值:

ptr != nullptr
Run Code Online (Sandbox Code Playgroud)

要么

!ptr
Run Code Online (Sandbox Code Playgroud)

(感谢其操作员bool).

  • @Jefffrey除非你的目标是混淆,否则要避免使用`!ptr`.它存在于模拟原始指针,但这是从C继承的原始指针的错误,应该在编写良好的代码中避免(即使在C中). (8认同)
  • ...或只是`!ptr` (2认同)
  • @JamesKanze C 和 C++ 都部分地基于 `0 == false` 的假设工作,这到处都是,你无法避免它,更不用说远离它了。这种联想刻在了我程序员的脑子里,虽然我已经很久没有接触 C 了,我想很多其他 C++ 程序员也有这种感觉。 (2认同)
  • *ptr 和 ptr-&gt; 相当于:*get() 和 get()。这不是未定义的,你为什么说它是未定义的? (2认同)

Jam*_*nze 17

在这方面,大多数共享指针与普通指针完全相同.你必须检查null.根据功能,您可能希望切换到使用

void myFunction( Foo const& foo );
Run Code Online (Sandbox Code Playgroud)

,并通过解除引用指针来调用它(它推动了确保指针对调用者不是null的责任).

此外,除非涉及一些特殊的所有权语义,否则使函数采用共享指针可能是不好的做法.如果函数只是在函数持续时间内使用指针,既不更改它也不取得所有权,原始指针可能更合适,因为它对调用者施加的约束较少.(但这实际上很大程度上取决于函数的作用,以及为什么使用共享指针.当然,事实上你已经传递了一个非const引用的共享指针,假设你要修改它,所以传递共享指针可能是合适的.)

最后,共享指针的不同实现使得检查null或多或少变得困难.使用C++ 11,您可以使用std::shared_ptr,并且只是nullptr 按照您的预期自然地进行比较.然而,Boost实现在这方面有点破裂; 你不能只把它与0或比较 NULL.您必须boost::shared_ptr为比较构造一个空 ,或者调用get它并将得到的原始指针与0或进行比较NULL.