Smart pointers declared const
could only invoke the member functions marked with const
. So their usage is very limited.
1.For unique pointers, you could not change the transfer the ownership of the managed object to another unique_ptr
and not even return it from a specific function.
So my question is that when const unique_ptr<T>
should be used? Some simple example may help me to understand it better.
2.For shared pointers, I think it's meaningless to use const shared_ptr<T>
because you can never increase the counter of a specific const shared pointer.
If I wrong, please let me know.
CodePudding user response:
Re: Non-transferrable unique pointers
Yes, that's the point. If you have a const object you cannot modify it. Transferring ownership of a pointer either from or to a const unique_ptr
is therefore not allowed.
Example:
struct ResourceUser {
ResourceUser() : mResource(CoupleMeWithSomeResource(this)) {}
private:
const unique_ptr<SomeResource> mResource;
};
Now an instance of ResourceUser
outright owns a resource that is in some way linked back to this object's address. You don't ever want that object to move in memory. Without needing any additional syntax, something like ResourceUser a, b; a = move(b);
is disallowed. Yaay!
Not even return it from a specific function
The only useful reason to return a unique pointer from a function is when you have created some value that is passed back to the caller or you are yielding ownership of something -- actually these are the same thing. It makes no sense to make it const. So yeah, irrelevant. Don't use a hammer to drive in a screw.
CodePudding user response:
One potential use-case would be when you've called a function that returns a shared_ptr
or unique_ptr
to you, and you want the compiler to guarantee that the access to that object can't escape your function, e.g.:
void Foo()
{
// tagging blah as const to be sure that
// no reference to the object blah points
// to will be retained after this function
// returns
const unique_ptr<Bar> blah = getBar();
[...]
someGlobalVariable = blah; // compile-time error -- nice try!
}
... as for why you'd want to do that... Foo() might do something that will make future access to *blah
unsafe, and so the best way to avoid unpleasant runtime bugs is to have the compiler ensure that those accesses cannot happen, even if someone modifies your function to try to allow it. Code that can defends itself against future maintenance programmers is less likely to gather bugs :)