I have a class Foo
class Foo;
a factory returning a pointer to it:
std::unique_ptr<Foo> createFoo();
and, since I have been told by Herb that a plain function with no special claim on the lifetime of Foo should take plain naked pointers:
void plainf(Foo* f);
How is my client supposed to correctly do this?
plainF(createFoo());
He would not be happy if he had to write:
auto someName = createFoo(); plainF(someName.get());
Reason Passing a smart pointer transfers or shares ownership and should only be used when ownership semantics are intended (see R. 30). Passing by smart pointer restricts the use of a function to callers that use smart pointers. Passing a shared smart pointer (e.g., std::shared_ptr) implies a run-time cost.
A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.
C++11 includes a solution: "weak" smart pointers: these only "observe" an object but do not influence its lifetime. A ring of objects can point to each other with weak_ptrs, which point to the managed object but do not keep it in existence.
You can use the get
member function which returns a raw pointer to the owned object.
plainF(createFoo().get());
The temporary created by createFoo()
will not go out of scope until plainF
has finished. So long as plainF
doesn't pass the pointer up out of scope this is completely safe.
If you don't need the argument to plainF
to be nullable, you can also change its signature to take the argument by reference, allowing for a slightly less verbose syntax:
std::unique_ptr<Foo> createFoo(); void plainf(Foo& f); plainF(*createFoo());
All the lifetime considerations mentioned in NathanOliver's answer apply, so this is just as safe to use.
Note that this implies that createFoo
will never return an empty unique_ptr
. So if that function is allowed to fail, you must indicate that error through other means, eg. by throwing an exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With