1

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])?

5
  • 1
    Does this answer your question? Proper way to create unique_ptr that holds an allocated array Commented May 8, 2022 at 8:13
  • @PepijnKramer It is about an array with explicit initialisation of an instance of a class, not just a plain allocated array Commented May 8, 2022 at 8:15
  • You will have to either use pointers in such an array, or allocate required space by manipulating bytes (char) and then assign initialized values. However before you do that, why don't you just use std::vector? Commented May 8, 2022 at 8:25
  • @RichardCritten where do I put arguments for the constructor? Commented May 8, 2022 at 8:26
  • You could also simply derive from std::array<MyClass, N> and provide a constructor. Then use a unique_ptr to that class. Commented May 8, 2022 at 8:43

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

8 Comments

Can I call my constructor here somehow? If creating a single instance, it looks like MyClass instance(arguments). Apart from initialising members, the constructor also has some calculations under the hood, which should also be done
@Kaiyakha Yes, you replace ... with arguments. If you must use paranthesized initialization instead of list-initialization with braces, you can replace {...} with MyClass(arguments) as well.
Is there any way to have one (arguments) for all elements of the array?
the amount of instances is not known at compile time, sorry for not mentioning that
@Kaiyakha Then what you are trying to do is impossible. Use std::vector instead.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.