Home > OS >  Proper syntax for defining a unique_ptr array of class objects with a constructor
Proper syntax for defining a unique_ptr array of class objects with a constructor

Time:05-08

I want an array of class objects with unique_ptr:

std::unique_ptr<MyClass[]> arr(new MyClass[n]);

MyClass has no default constructor (and in my case is not supposed to have), so I have to put it explicitly here. I cannot find out how to do it so it is syntactically correct. What is the correct way to write a unique_ptr array of class objects with explicit initialisation?

Clarification

I have a non-default constuctor for MyClass, like this:

MyClass instance(arguments);

Apart from member initialisations, there are also some calculations in the constructor. I want to create a unique_ptr array of MyClass instances and call the constructor for each of the instances. I cannot do that later since MyClass has no default constructor. Can I put (arguments) somewhere in std::unique_ptr<MyClass[]> arr(new MyClass[n])?

CodePudding user response:

The answer below is based on a previous version of the question, in which the array size appeared to be a compile-time constant. If the size of the created array is not a compile-time constant, then it is impossible to pass arguments to the constructors of the elements. In that case std::vector is probably a better choice than array-std::unique_ptr.


It works the same as always for arrays, using aggregate initialization:

std::unique_ptr<MyClass[]> arr(new MyClass[]{
    {...},
    {...},
    {...},
    {...},
    {...}});

where ... are replaced by the argument lists for the constructors of the five elements.

Or if you cannot use list-initialization for the elements, e.g. because that would unintentionally use a std::initializer_list constructor:

std::unique_ptr<MyClass[]> arr(new MyClass[]{
    MyClass(...),
    MyClass(...),
    MyClass(...),
    MyClass(...),
    MyClass(...)});

std::make_unique would usually be preferred for creating std::unique_ptrs, but there is at the moment no overload which allows passing arguments to the constructors of the individual array elements.


If you want to pass the same argument list to each element, a simple solution given that the type is copy-constructible would be to declare one instance and then copy-construct the elements from this instance:

MyClass instance(arguments);
std::unique_ptr<MyClass[]> arr(new MyClass[]{instance, instance, instance, instance, instance);

Otherwise you could write a template function that expands these repeated items for you. (Might add example later.)

  • Related