How to pass shared_ptr to class with lower lifetime?

混江龙づ霸主 提交于 2019-12-01 08:47:57

In this case when you know the life-time of your shared resource will outlive those that you pass the pointer to the correct thing to do is pass a reference or a raw pointer:

void func(object* o)
{
    // do stuff with o
} 

// ...

std::shared_ptr<object> sp;

// ...

func(sp.get()); // pass raw pointer

The main reason for this is that the function can be useful no matter what kind of smart pointer is managing the resource. By accepting the raw pointer your function is able to accept objects from shared pointers as well as unique pointers and any other third party smart pointer.

There is no benefit to passing in the smart pointer unless the function needs to modify the smart pointer itself.

A good set of guidelines being produced by Bjarne Straustrup & Herb Sutter can be found here: CppCoreGuidelines

The rule about passing raw pointers (or references): R.30

Accepting a smart pointer to a widget is wrong if the function just needs the widget itself. It should be able to accept any widget object, not just ones whose lifetimes are managed by a particular kind of smart pointer. A function that does not manipulate lifetime should take raw pointers or references instead.

When passing the shared_ptr into a function that will not store the resource, pass it by reference:

void foo(const shared_ptr<T>& ptr)
{
    // Basically just a pointer dereference
    std::cout << ptr->bar() << '\n';
}

int main()
{
   std::shared_ptr<T> ptr{std::make_shared<T>()};
   foo(ptr);
}

That won't increment the reference count, but that's fine — you're effectively treating it as a raw pointer (because you're just temporarily inspecting the pointee) but in a way that's safe because if you accidentally copy it then you'll get the reference count increment that can save your life. :)

However, if foo needs to store any sort of handle to this object, then you should pass in the shared_ptr by copy … or consider using weak_ptr so that you at least get some semblance of safety.

The above contrived example is so simple that I'd actually make it the following:

void foo(const T& ptr)
{
    std::cout << ptr.bar() << '\n';
}

int main()
{
   std::shared_ptr<T> ptr{std::make_shared<T>()};
   foo(*ptr.get());
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!