C++ 返回 null shared_ptr 是否正确?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37234969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:40:50  来源:igfitidea点击:

Is it correct to return null shared_ptr?

c++shared-ptrsmart-pointersweak-ptr

提问by John Lock

For example, there is a function that finds an object and returns shared_ptr if object is found, and must indicate somehow that no object was found.

例如,有一个函数可以找到一个对象并在找到对象时返回 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. Is it correct to return shared_ptr implicitly initialized with nullptr like in upper example? It will work, but can be it done this way? Or should I return shared_ptr default constructed instead?

  2. What in case it would be weak_ptr? What is proper way to check that empty weak_ptr has been returned? by weak_ptr::expired function or are there other ways? If checking by weak_ptr::expired is the only way then how can I distinguish that function returned empty pointer, or object was just deleted(multi-thread environment)?

  1. 像上例那样返回使用 nullptr 隐式初始化的 shared_ptr 是否正确?它会起作用,但是可以这样做吗?或者我应该返回默认构造的 shared_ptr 吗?

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

回答by anton_rh

Is it correct to return shared_ptr implicitly initialized with nullptr like in upper example?

像上例那样返回使用 nullptr 隐式初始化的 shared_ptr 是否正确?

Yes, it is correct to initialize shared_ptrwith nullptr. It is also correct to assign nullptrto shared_ptr.

是的,这是正确的初始化shared_ptrnullptr。分配nullptr给也是正确的shared_ptr

Or should I return shared_ptr default constructed instead?

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

You can do this in both ways:

您可以通过两种方式执行此操作:

  1. returning shared_ptrinitialized with nullptr

    return shared_ptr<Object>(nullptr);
    
  2. returning shared_ptrdefault constructed.

    return shared_ptr<Object>();
    
  1. 返回shared_ptr初始化为nullptr

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

    return shared_ptr<Object>();
    

Both ways are correct and both have the same effect. You can use whatever way you want.

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

What in case it would be weak_ptr? What is proper way to check that empty weak_ptr has been returned? by weak_ptr::expired function or are there other ways?

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

weak_ptrbecomes nullptr(expires) whenever the last shared_ptrassociated with object is destroyed.

weak_ptrnullptr每当最后一个shared_ptr与对象相关联的对象被销毁时就变为(过期)。

The proper way to work with weak_ptris to convert it to shared_ptrwith lockmethod, and then to work with created shared_ptr. In that case your weak_ptrwill no expire until you have that new shared_ptr. If you don't convert weak_ptrinto shared_ptr, your weak_ptrmay expire at any moment.

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

And yes, before working with newly created shared_ptr, you must check that it isn't null, because weak_ptrmay had been expired before you created shared_ptrwith lockmethod.

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

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.
}