1

I'm working with a dynamic array of a given class, let's call it 'MyClass', the thing is this class has a specialized constructor with a given parameter.

As far as I know to initialize a dynamic array I should use this:

MyClass *myArray = new MyClass[]();

Is there a way to initialize my array using my specialized constructor? something like:

MyClass *myArray = new MyClass[](givenParameter);

and this got me to another question, what does the line MyClass *myArray = new MyClass[](); is it calling a base constructor without any given parameters or does it do something else internally?

It may be something obvious but I wasn't able to find much information on this, at least not something to solve my first question. Thank you, everyone.

2 Answers 2

2

The syntax MyClass *myArray = new MyClass[size](); allows you to value-initialize the elements when they are trivial simple types (like integers, etc, thus setting them to 0), but it is not very meaningful for elements of class/struct types, so the () is usually omitted for those types. new[] can only call default constructors on class/struct types, it does not allow you to call non-default constructors.

However, a way to handle that is to use placement-new instead, which would then allow you to construct each MyClass object individually, even with different parameter values if needed.

// allocate raw memory to hold the objects array...
char *myArrayBuf = new char[sizeof(MyClass) * NumberOfItems];
/* alternatively, in C++11 and later:
#include <type_traits>
using element_type = std::aligned_storage<sizeof(MyClass), alignof(MyClass)>::type;
element_type *myArrayBuf = new element_type[NumberOfItems];
*/

// call the constructor on each object in the array...
MyClass *myArray = reinterpret_cast<MyClass*>(myArrayBuf);
for(int i = 0; i < NumberOfItems; ++i) {
    new(&myArray[i]) MyClass(givenParameter);
}

// use myArray as needed ...

// call the destructor on each object in the array...
for(int i = 0; i < NumberOfItems; ++i) {
    myArray[i].~MyClass();
}

// deallocate the raw memory for the array...
delete[] myArrayBuf;

In C++11 and later, this would be easier to handle using a std::vector instead (which you should be using anyway):

#include <vector>

std::vector<MyClass> myArray;
myArray.reserve(NumberOfItems);

for(int i = 0; i < NumberOfItems; ++i) {
    myArray.emplace_back(givenParameter);
}

// use myArray as needed ...

Prior to C++11, you can still use std::vector, but it would require copy-constructing the array elements:

#include <vector>

std::vector<MyClass> myArray;
myArray.reserve(NumberOfItems);

for(int i = 0; i < NumberOfItems; ++i) {
    myArray.push_back(MyClass(givenParameter));
}

// use myArray as needed ...
Sign up to request clarification or add additional context in comments.

Comments

2
MyClass *arr;
arr = new MyClass[2]{{10, "hello"},{20, "custom constructor"}};

I'm not sure there's another way to initialize C-array with non-standard constructor.

But if you're ok with using std::vector then:

#include <vector>
size_t size = 2;
std::vector<MyClass> myArray(size, MyClass(givenParameter));

3 Comments

Just note that the 1st syntax only works if you can hard-code the elements in the array, it is not very suitable for large arrays, and does not work if the element count is not known at compile-time. The 2nd syntax copy-constructs all of the array elements using the single object passed to the vector constructor as the input to copy, so it is not useful if you need to construct each element with different parameters.
Just to add to your remark: the 2nd case with using the constructor may be resolved with a loop and .emplace(givenParameter) method. And we may define and use a custom allocator with empty construct() member function using a DefaultInsertable concept.
Oh yeah, I forgot about emplace_back(), thanks. In that case, you would have to reserve() the vector, not specify a size in its constructor. But using a custom allocator is not something most people do, though.

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.