3

My class has this member:

static std::unique_ptr<std::unique_ptr<ICommand>[]> changestatecommands;

and I cannot find the correct way to initialize this. I want the array to be initialized, but the elements uninitialized, so I can at any time write something like:

changestatecommands[i] = std::make_unique<ICommand>();

It does not matter if the array is initialized immediately at the declaration, or later in runtime. Optimally, I would like to know how to do both.

JeJo
  • 30,635
  • 6
  • 49
  • 88
Viktor Axén
  • 199
  • 2
  • 11
  • Why not just a simple vector of pointers, as in `std::vector` (or `std::vector>` if you want ownership semantics). – Some programmer dude Dec 27 '19 at 13:47
  • 6
    Is there a reason why you don't use `std::vector>`? – t.niese Dec 27 '19 at 13:47
  • Read that https://stackoverflow.com/questions/16711697/is-there-any-use-for-unique-ptr-with-array/16711846 It has to be last resort solution and those usually smell bad. – Öö Tiib Dec 27 '19 at 13:52
  • @t.niese no actually not. I'm just learning about smart pointers, so I guess I got caught up in it and use the m for everything. Would there be any benefits to using a unique_ptr as I have, or is it the exact same thing? – Viktor Axén Dec 27 '19 at 13:53
  • 2
    I think there are only significant disadvantages to use `unique_ptr[]` as you have. – Fantastic Mr Fox Dec 27 '19 at 13:56
  • 1
    It is more about avoiding c style array (`std::unique_ptr[]`), and using an std container instead. – t.niese Dec 27 '19 at 14:11
  • See also https://stackoverflow.com/questions/21377360/proper-way-to-create-unique-ptr-that-holds-an-allocated-array – Phil1970 Dec 27 '19 at 14:20
  • Whenever you have a question about C++, one of the first place to look is **CPP reference**. Look case (2) here: https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique. – Phil1970 Dec 27 '19 at 14:23

1 Answers1

6

How to initialize std::unique_ptr<std::unique_ptr<ICommand>[]>?

Like this

#include <memory>

std::unique_ptr<std::unique_ptr<ICommand>[]> changestatecommands{
    new std::unique_ptr<ICommand>[10]{nullptr}
};

// or using a type alias
using UPtrICommand = std::unique_ptr<ICommand>;
std::unique_ptr<UPtrICommand[]> changestatecommands{ new UPtrICommand[10]{nullptr} };

//or like @t.niese mentioned
using UPtrICommand = std::unique_ptr<ICommand>;
auto changestatecommands{ std::make_unique<UPtrICommand[]>(10) };

However, as others mentioned, think about the alternatives, such as

std::vector<std::unique_ptr<ICommand>>  // credits  @t.niese

before coming into the above conclusion.

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • 1
    I would use `std::make_unique[]>(10)` instead, in combination with `auto`: `auto changestatecommands = std::make_unique[]>(10)` – t.niese Dec 27 '19 at 14:31
  • @t.niese Also possible. Let me add it to the answer. – JeJo Dec 27 '19 at 14:34