I'm wondering when we should use unique_ptr
(or boost::scope_ptr
) instead of local object.
There are two possible cases I can think of:
The object is large that exceed stack size of a thread. But in this case you can always increase size of thread.
Polymorphism. e.g. unique_ptr<C> p; if ... p.reset(new C1); else p.reset(new C2);
. But I am not sure when exactly we need this. If this p
is a parameter for a function, we can simply say: if ... foo(new C1); else foo(new C2);
Are there any other cases that we should use unique_ptr
instead of local object?
When to use unique_ptr? Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another.
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.
The unique_ptr class supersedes auto_ptr , and can be used as an element of C++ Standard Library containers. Use the make_unique helper function to efficiently create new instances of unique_ptr . unique_ptr uniquely manages a resource.
unique_ptr::getReturns a pointer to the managed object or nullptr if no object is owned.
Polymorphism is a common reason. A typical example is your object is created by a factory that returns a unique_ptr
:
std::unique_ptr<C> factoryFunction(int arg) {
switch (arg) {
case 1:
return std::make_unique<C1>();
case 2:
return std::make_unique<C2>();
default:
return nullptr;
}
}
void someFunction(int arg) {
auto c = factoryFunction(arg);
if (c) {
// do something with c...
}
}
In your comment you say you prefer shared_ptr
if you need a variable that lives longer than the scope it is declared. I think you should actually prefer unique_ptr
. By returning a unique_ptr
you are transferring ownership to the caller. Like factoryFunction
does above. Or perhaps to return a big expensive-to-move object:
using BigArray = std::array<BigPOD, 1000>;
std::unique_ptr<BigArray> getBig() {
auto big = std::make_unique<BigArray>();
// fill big...
return big;
}
unique_ptr
has less overhead than shared_ptr
and it makes ownership clearer. I would only use shared_ptr
if ownership needs to be shared.
Passing a unique_ptr
into a function means you are transferring ownership into the function (a "sink"). For example a constructor:
class Foo {
private:
std::unique_ptr<BigArray> array_;
public:
Foo(std::unique_ptr<BigArray> array) : array_(std::move(array)) {}
};
void someFunction() {
auto big = getBig();
auto foo = Foo(std::move(big));
// do something with foo...
}
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