Самый короткий ответ, вероятно, будет «определение - исполнение», поэтому весь аргумент не имеет строгой точки зрения. В качестве более надуманного примера вы можете привести следующее:
def a(): return []
def b(x=a()):
print x
. Надеюсь, этого достаточно, чтобы показать, что не выполнять выражения аргументов по умолчанию во время выполнения инструкции def
не просто или не работает, т. е. смысл, или и то, и другое.
Я согласен с тем, что при попытке использовать конструкторы по умолчанию, это будет gotcha.
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
});
Вы также можете сделать что-то подобное:
MyClass *myVar[num];
for(int i = 0; i < num; i += 1)
{
myVar[i] = new MyClass(0, 0);
}
Один из способов, которые я сделал в прошлом, - использовать двойной указатель.
MyClass ** myvar;
myvar = new Myclass*[num]
for(int i = 0; i < 4; i++){
*(myvar+i) = new Myclass(i);}
Работает с практически любой структурой управления, которую вы можете себе представить, единственным препятствием является то, что объекты не являются обязательно будет последовательно в куче.
В C ++ 0x эта грамматика работает, которая может вызывать конструктор не по умолчанию в новом выражении:
MyClass *myVar;
myVar = new MyClass[2]{{10, 20},{20, 30}};
Но я сомневаюсь, что он работает, когда количество элементов доступно только при
Векторный подход был бы лучше, как показано в ответе Наваза.
На самом деле вы можете использовать новое место размещения для этого:
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);
}
delete[] reinterpret_cast<char *>(myVar);
.
– M.M
24 June 2015 в 15:07
std::vector
. Это потрясающий контейнер с множеством интересных функций. – Nawaz 11 December 2011 в 11:35