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 this p

    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?

+3


source to share


1 answer


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...
}

      

+4


source







All Articles