Вызов конструктора с параметрами с новым [] [duplicate]

Самый короткий ответ, вероятно, будет «определение - исполнение», поэтому весь аргумент не имеет строгой точки зрения. В качестве более надуманного примера вы можете привести следующее:

def a(): return []

def b(x=a()):
    print x

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

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

16
задан user972276 11 December 2011 в 11:29
поделиться

5 ответов

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-constructor класса, передавая ему 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 вы можете использовать lambda как:

std::for_each(arr.begin(), arr.end(), [](const MyClass & m)
                                      {
                                           //working with m 
                                      });
22
ответ дан Nawaz 20 August 2018 в 22:43
поделиться
  • 1
    Спасибо, что помогли! Я действительно искал подход, используя массивы вместо векторов, потому что мой учитель хотел, чтобы класс использовал массивы. Однако я нашел ответ. – user972276 11 December 2011 в 11:33
  • 2
    @ user972276: для массивов ваш первый подход - это то, что можно сделать, если вы хотите вызвать конструктор, отличный от стандартного. Однако в будущем, если вам когда-либо понадобится массив, first рассмотрим использование std::vector. Это потрясающий контейнер с множеством интересных функций. – Nawaz 11 December 2011 в 11:35

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

MyClass *myVar[num];

for(int i = 0; i < num; i += 1)
{
    myVar[i] = new MyClass(0, 0);
}
0
ответ дан Akib Imtiaz 20 August 2018 в 22:43
поделиться

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

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

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

2
ответ дан Connor Farrell 20 August 2018 в 22:43
поделиться

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

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

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

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

6
ответ дан fefe 20 August 2018 в 22:43
поделиться

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

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);
}
0
ответ дан Marc De Scheemaecker 20 August 2018 в 22:43
поделиться
  • 1
    Вы должны использовать std::aligned_storage вместо new char[]. – M.M 24 June 2015 в 15:06
  • 2
    Также следует упомянуть, что для освобождения этой памяти вы должны пройти цикл и вызвать деструкторы каждого объекта, а затем вызвать delete[] reinterpret_cast<char *>(myVar);. – M.M 24 June 2015 в 15:07
Другие вопросы по тегам:

Похожие вопросы: