Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does std::unique_ptr not have a const get method?

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.

like image 543
quittle Avatar asked May 18 '17 16:05

quittle


People also ask

Why would you choose Shared_ptr instead of unique_ptr?

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.

What happens when unique_ptr goes out of scope?

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.

Can unique_ptr be passed to function?

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.


2 Answers

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.


Based on comment below:

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.

like image 186
Marek R Avatar answered Nov 09 '22 19:11

Marek R


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:

like image 28
Ben Voigt Avatar answered Nov 09 '22 20:11

Ben Voigt