【问题标题】:Is it correct to return null shared_ptr?返回 null shared_ptr 是否正确?
【发布时间】:2016-09-11 02:59:10
【问题描述】:

例如,有一个函数可以找到一个对象,如果找到对象则返回 shared_ptr,并且必须以某种方式表明没有找到对象。

std::vector<std::shared_ptr> Storage::objects;

std::shared_ptr<Object> Storage::findObject()
{
  if (objects.find)
  {
    return objects[x];
  }
  else
  {
    return nullptr;
  }
}

std::shared_ptr<Object> obj = Storage::findObject();
if (obj)
{
  print("found");
}
else
{
  print("not found");
}
  1. 返回 shared_ptr 使用 nullptr 隐式初始化是否正确,如上例所示?它会起作用,但可以这样做吗?还是应该返回 shared_ptr 默认构造的?

  2. 万一是weak_ptr呢?检查是否返回了空的weak_ptr的正确方法是什么?通过 weak_ptr::expired 函数还是有其他方法?如果通过 weak_ptr::expired 检查是唯一的方法,那么我如何区分该函数返回空指针,或者对象刚刚被删除(多线程环境)?

【问题讨论】:

  • @AndersK。找不到对象的情况与找到对象一样常见。
  • 如果你可以使用 boost,optional&lt;T&gt; 似乎正是你想要的(这似乎成为 C++17 的标准)。如果您不想要开销,那么您基本上只需要记录 nullptr 实际上是没有价值而不是错误。
  • @JohnLock:不,没有区别。
  • @BenjaminLindley:来自 (cplusplus.com/reference/memory/shared_ptr) - “不拥有任何指针的 shared_ptr 称为空 shared_ptr。指向没有对象的 shared_ptr 称为 null shared_ptr 并且不应被取消引用. 请注意,空的 shared_ptr 不一定是空的 shared_ptr,空的 shared_ptr 也不一定是空的 shared_ptr。”
  • @JohnLock:错了。

标签: c++ shared-ptr smart-pointers weak-ptr


【解决方案1】:

返回 shared_ptr 隐式初始化为 nullptr 是否正确?

是的,用nullptr 初始化shared_ptr 是正确的。将nullptr 分配给shared_ptr 也是正确的。

或者我应该返回默认构造的 shared_ptr 吗?

您可以通过两种方式做到这一点:

  1. 返回用nullptr初始化的shared_ptr

    return shared_ptr<Object>(nullptr);
    
  2. 返回shared_ptr 默认构造。

    return shared_ptr<Object>();
    

这两种方式都是正确的,并且都具有相同的效果。你可以使用任何你想要的方式。

万一是weak_ptr呢?检查是否返回了空的weak_ptr的正确方法是什么?通过weak_ptr::expired函数还是有其他方法?

只要与对象关联的最后一个shared_ptr 被销毁,weak_ptr 就会变为nullptr(过期)。

使用weak_ptr 的正确方法是使用lock 方法将其转换为shared_ptr,然后使用创建的shared_ptr。在这种情况下,您的weak_ptr 在您拥有新的shared_ptr 之前不会过期。如果您不将weak_ptr 转换为shared_ptr,您的weak_ptr 可能随时过期。

是的,在使用新创建的shared_ptr 之前,您必须检查它是否为空,因为在您使用lock 方法创建shared_ptr 之前weak_ptr 可能已经过期。

std::weak_ptr<Object> Storage::findObject();

...

std::weak_ptr  <Object> weak   = Storage::findObject();
std::shared_ptr<Object> shared = weak.lock();
if (shared) // check that weak was not expired when we did "shared = weak.lock()"
{
    // do something with shared, it will not expire.
}

【讨论】:

  • 我不会使用return shared_ptr&lt;Object&gt;(nullptr);,因为return shared_ptr&lt;Object&gt;(); 就足够了。这是一种风格偏好:我不写不必要的东西,因为它可能会让别人认为它们是必要的。有时其他人可能会从你写的东西中学习,并可能会产生误解。
猜你喜欢
  • 2015-12-30
  • 2019-01-27
  • 2014-11-24
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
相关资源
最近更新 更多