问题
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 thewidget
itself. It should be able to accept anywidget
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