How to pass shared_ptr to class with lower lifetime?

别来无恙 提交于 2020-01-21 08:49:25

问题


I'd like to optimize my code. I have one class that have shared_ptr data member. In some method of this class I create objects that need use this member (just to get information from object pointed by shared_ptr). I know that lifetime of these created objects is lower than my main class. How to pass this pointer? I think another shared_ptrs are unnecessary (because I have warranty that object will exist). So what should get my created classes? Should they get raw pointer? Weak_ptr? Or the best solution is getting shared_ptr (and incrementing its reference counter)? What is the most standard solution?


回答1:


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.




回答2:


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());
}


来源:https://stackoverflow.com/questions/35543520/how-to-pass-shared-ptr-to-class-with-lower-lifetime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!