When to use unique_ptr instead of local object?
I'm wondering when should we use unique_ptr
(or boost::scope_ptr
) instead of a local object.
There are two possible cases I can think of:
-
The object is large and exceeds the size of the thread's stack. But in this case, you can always increase the size of the stream.
-
polymorphism. for example
unique_ptr<C> p; if ... p.reset(new C1); else p.reset(new C2);
. But I'm not sure exactly when we need it. If thisp
is a parameter to a function, we can simply say:if ... foo(new C1); else foo(new C2);
Are there other cases we should use unique_ptr
instead of a local object?
source to share
Polymorphism
Polymorphism is a common cause. A typical example is that your object is created by a factory that returns 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...
}
}
Transfer of ownership
In your comment, you say you prefer shared_ptr
if you want a variable that lives longer than the declared scope. I think you should prefer unique_ptr
. By returning unique_ptr
, you transfer ownership of the caller. For example, factoryFunction
does the above. Or perhaps to return a large, expensive 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 makes it more understandable. I would only use it shared_ptr
if it is necessary to share ownership.
Passing unique_ptr
to a function means that you are transferring ownership of the function ("sink"). For example the 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...
}
source to share