I understand that std::unique_ptr
is the way it is and probably won't be changed to break backwards compatibility but I was wondering if anyone has a good reason why the writers of the spec didn't overload the get
method with a const variant that looks like
const T* get() const;
to follow the intent of the unique_ptr
being const
.
My best guess is that it is trying to mirror pointers and act like a T* const
instead of a typical class. As a follow-up question, if I wanted to hold a pointer in a const-like fashion in a const instance of my class, should I be using something else other than std::unique_ptr
to hold the data?
Update
In my case I want to protect myself from misusing the pointer in the class itself. I was writing a const move constructor MyClass(const MyClass&& other)
and was copying the data from the new instance into other via std::copy
. It took a long time to track down the bug because I had assumed the copy must be correct because of const protection. I'm trying to figure out what I could have done to protect myself from this outside of providing a const getter and using that within the class when doing the copy.
In short: Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.
unique_ptr. An unique_ptr has exclusive ownership of the object it points to and will destroy the object when the pointer goes out of scope.
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.
Smart pointers are pretending to be a raw pointer.
If you have class member which is raw pointer and use it in const
method that you can't update a pointer, but you can modify object which is pointed.
Same behavior is desired for smart pointer. So std::unique_ptr::get
is a const
method, but doesn't force to return pointer to const
object.
Note also that you can have a pointer to const
object.
MyClass *pointerToObject
std::unique_ptr<MyClass> smartPointerToObject;
// but you can have also a case
const MyClass *pointerToConstObject
std::unique_ptr<const MyClass> smartPointerToConstObject;
In last case std::unique_ptr::get
will return something you are expecting.
Just provide private methods:
InnerClass& GetField() { return *uniquePtrToInnerClass; }
const InnerClass& GetField() const { return *uniquePtrToInnerClass; }
And use it in your code and you will have const object of inner class in const method.
There's no point to giving read-only access to an object via its unique_ptr
. You only pass unique_ptr
around when you are transferring ownership, for access to the object without an ownership transfer, call up.get()
and pass a const T*
to the function that should only read (or if the pointer is never nullptr
, it's also reasonable to evaluate *(up.get())
and pass a const T&
).
As a bonus, this allows you to use that function with objects stored on the stack, embedded inside another object, or managed with a smart pointer other than unique_ptr
.
There's a good discussion of all the unique_ptr parameter passing cases (in/out, const/non-const, etc) here:
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