Инициализация динамического массива c - PullRequest
1 голос
/ 09 апреля 2020

Я работаю с динамическим c массивом данного класса, давайте назовем его «MyClass», дело в том, что у этого класса есть специализированный конструктор с данным параметром.

Насколько я знаю, чтобы инициализировать динамический c массив, я должен использовать это:

MyClass *myArray = new MyClass[]();

Есть ли способ инициализировать мой массив с помощью моего специализированного конструктора? что-то вроде:

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

, и это привело меня к другому вопросу: что означает строка MyClass *myArray = new MyClass[]();, вызывает ли она базовый конструктор без каких-либо заданных параметров или выполняет что-то еще внутри? ?

Это может быть что-то очевидное, но я не смог найти много информации по этому поводу, по крайней мере, не то, что решил мой первый вопрос. Спасибо всем.

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

Синтаксис MyClass *myArray = new MyClass[size](); позволяет вам инициализировать значения для элементов, когда они представляют собой тривиальные простые типы (например, целые числа и т. Д. c, устанавливая их в 0), но это не очень важно для элементов класса / структуры типы, поэтому () обычно не указывается для этих типов. new[] может вызывать конструкторы по умолчанию только для типов классов / структур, это не позволяет вам вызывать конструкторы не по умолчанию.

Однако способ обработки, который заключается в использовании placement-new вместо этого, что позволило бы вам создать каждый MyClass объект индивидуально, даже с различными значениями параметров, если это необходимо.

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

В C ++ 11 и более поздних версиях это будет легче обрабатывать с помощью std::vector вместо этого (который вы должны использовать в любом случае):

#include <vector>

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

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

// use myArray as needed ...

До C ++ 11 вы все еще можете использовать std::vector, но для этого потребуется копирование элементов массива:

#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 ...
2 голосов
/ 09 апреля 2020
MyClass *arr;
arr = new MyClass[2]{{10, "hello"},{20, "custom constructor"}};

Я не уверен, что есть другой способ инициализации массива C нестандартным конструктором.

Но если вы в порядке с использованием std :: vector, тогда:

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