Как динамически объявить массив объектов с помощью конструктора в C ++ - PullRequest
23 голосов
/ 11 декабря 2011

Мне было интересно, можно ли создать массив объектов, когда объект нуждается в вещах, переданных в него для конструктора.Я хочу что-то вроде этого:

MyClass *myVar;
myVar = new MyClass[num];  // I would like to specify the array size after declaration
int i = 0;
for(i = 0;i < num;i++)
   myVar[i] = new MyClass(0,0);  // I would also like to populate the array with new objects

Я знаю, что это работает:

MyClass *myVar;
myVar = new MyClass[num];

, но это работает, только когда в конструктор ничего не передается.Возможно ли то, что я пытаюсь сделать?Если да, то как мне это сделать?

РЕДАКТИРОВАТЬ: я узнал, как это сделать с использованием массивов.Вот как я это сделал:

MyClass **myVar;
myVar = new MyClass *[num];
for(i = 0;i < num;i++)
   myVar[0] = new MyClass(0,0);

Я бы использовал векторы и тому подобное, но мой учитель сказал нам по возможности использовать базовые массивы.Вышеупомянутое решение я фактически получил из некоторого кода, написанного моим учителем.Спасибо всем за помощь!

Ответы [ 5 ]

24 голосов
/ 11 декабря 2011
MyClass *myVar;
myVar = new MyClass[num];

На самом деле в этой форме вы не можете вызвать конструктор, который принимает параметры. Это не разрешено языковой спецификацией.

Однако, если вы используете std::vector, который я рекомендую вам использовать, тогда вы можете создать вектор, вызывающий конструктор не по умолчанию, как:

#include <vector> //header file where std::vector is defined

std::vector<MyClass>  arr(num, MyClass(10,20));

Создает вектор из num элементов, каждый элемент создается путем вызова copy-конструктора класса, передавая ему MyClass(10,20) в качестве аргумента.

Вектор также хорош, потому что теперь вам не нужно управлять памятью самостоятельно. Ни ручное распределение, ни ручное освобождение. Кроме того, вы можете узнать количество элементов, позвонив по номеру arr.size() в любое время. Вы всегда знаете, сколько элементов содержит вектор. Вы также можете добавлять элементы в любое время, просто вызвав .push_back() функцию-член как:

arr.push_back(MyClass(20,30)); 

И теперь вы можете обращаться к элементам так же, как к массиву, то есть с помощью индекса:

f(arr[i]); // 0 <= i < arr.size();

Кроме того, вы можете использовать итераторы, которые облегчают идиоматическое программирование, позволяя вам использовать различные алгоритмические функции из заголовка <algorithm> как:

#include <algorithm> //header file where std::for_each is defined

std::for_each(arr.begin(), arr.end(), f);

где f - функция, которая принимает один аргумент типа MyClass& (или MyClass const &) в зависимости от того, что вы хотите сделать в f.

В C ++ 11 вы можете использовать лямбду как:

std::for_each(arr.begin(), arr.end(), [](const MyClass & m)
                                      {
                                           //working with m 
                                      });
7 голосов
/ 11 декабря 2011

В C ++ 0x работает эта грамматика, которая может вызывать конструктор не по умолчанию в новом выражении:

MyClass *myVar;
myVar = new MyClass[2]{{10, 20},{20, 30}};

Но я сомневаюсь, что это работает, когда количество элементов доступно только при запускевремя.

Векторный подход был бы лучше, как показано в ответе Наваза.

3 голосов
/ 03 ноября 2014

Один способ, которым я делал это в прошлом, - это использование двойного указателя.

MyClass ** myvar;
myvar = new Myclass*[num]
for(int i = 0; i < 4; i++){
*(myvar+i) = new Myclass(i);}

Работает практически со всеми структурами элементов управления, которые вы можете себе представить, единственным недостатком является то, что объекты не обязательнобудет последовательно в куче.

1 голос
/ 15 мая 2017

Вы тоже можете сделать что-то подобное:

MyClass *myVar[num];

for(int i = 0; i < num; i += 1)
{
    myVar[i] = new MyClass(0, 0);
}
0 голосов
/ 24 июня 2015

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

MyClass * myVar;
myVar = reinterpret_cast<MyClass *>(new char[num * sizeof(MyClass)]);
int i = 0;
for (i = 0; i < num; i++) {
    new(&myVar[i]) MyClass(0,0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...