I'm trying to "modernize" some existing code.
This works well, but to "modernize" my code I thought I ought to change the variable to be defined as "std::unique_ptr<Device> device_"
and remove the explicit call to delete, which makes the code safer and generally better.
My question is this -
I can call .get to get the raw pointer in each function call. But that seems ugly and wastes some of the reasons to use a unique_ptr in the first place.
Or I can change every function so that instead of taking a parameter of type "Device*" it now takes a paramater of type "std::unique_ptr& ". Which (to me) somewhat obfuscates the function prototypes, and makes them hard to read.
What is best practice for this? Have I missed any other options?
Because the unique pointer does not have a copy constructor. Hence you cannot pass it by value, because passing by value requires making a copy.
Can I pass a unique_ptr's reference to a function? Yes, a unique_ptr is class like any other.
You cannot copy a unique_ptr . You can only move it. The proper way to do this is with the std::move standard library function. If you take a unique_ptr by value, you can move from it freely.
In Modern C++ style, there are two keys concepts:
Ownership is about the owner of some object/resource (in this case, an instance of Device
). The various std::unique_ptr
, boost::scoped_ptr
or std::shared_ptr
are about ownership.
Nullity is much more simple however: it just expresses whether or not a given object might be null, and does not care about anything else, and certainly not about ownership!
You were right to move the implementation of your class toward unique_ptr
(in general), though you may want a smart pointer with deep copy semantics if your goal is to implement a PIMPL.
This clearly conveys that your class is the sole responsible for this piece of memory and neatly deals with all the various ways memory could have leaked otherwise.
On the other hand, most users of the resources could not care less about its ownership.
As long as a function does not keep a reference to an object (store it in a map or something), then all that matters is that the lifetime of the object exceeds the duration of the function call.
Thus, choosing how to pass the parameter depends on its possible Nullity:
It really depends. If a function must take ownership of the unique_ptr, then it's signature should take a unique_ptr<Device>
bv value and the caller should std::move
the pointer. If ownership is not an issue, then I would keep the raw pointer signature and pass the pointer unique_ptr using get()
. This isn't ugly if the function in question does not take over ownership.
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