Marc Bofias
Marc Bofias

Reputation: 13

Initializing a dynamic array

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.

Upvotes: 1

Views: 214

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 595827

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

Upvotes: 2

vamirio-chan
vamirio-chan

Reputation: 351

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

Upvotes: 2

Related Questions