2010-09-21 6 views
12

В C++, я могу статический инициализировать массив, например .:Есть ли способ статически инициализировать динамически выделенный массив в C++?

int a[] = { 1, 2, 3 }; 

Есть простой способ инициализировать динамически выделенный массив множество непосредственных значений?

int *p = new int[3]; 
p = { 1, 2, 3 }; // syntax error 

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

+0

О чем вы возражаете? Необходимость написания кода для инициализации вектора? Время, необходимое для копирования? Обратите внимание, что любой трюк компилятора для инициализации динамически выделенного массива будет включать одно и то же копирование, поскольку невозможно гарантировать, что выделенная память поставляется с точным правильным содержимым. –

+0

Если производительность сущности, почему вы динамически выделяете вообще? Почему косвенность через указатель? Поскольку вы все равно статически инициализируете массив, наверняка размеры матриц известны во время компиляции? – fredoverflow

+0

Я ни о чем не возражаю, просто спрашиваю. Я использую собственный класс матрицы, который хранит данные в динамически распределенном массиве, и я подумал, что это хорошо, если я могу инициализировать этот массив без копирования данных вручную. :) – neuviemeporte

ответ

27

Вы может в C++ 0x:

int* p = new int[3] { 1, 2, 3 }; 
... 
delete[] p; 

Но я лучше люблю векторы:

std::vector<int> v { 1, 2, 3 }; 

Если у вас нет C++ 0x компилятора, подталкивание может помочь вам:

#include <boost/assign/list_of.hpp> 
using boost::assign::list_of; 

vector<int> v = list_of(1)(2)(3); 
+5

'+ 1' для' std :: vector'. Какая причина, по-прежнему, использовать ваши собственные динамические массивы? – sbi

+0

@sbi Согласовано, кажется, что вам нечего делать, когда векторы становятся намного приятнее. – EricBoersma

+0

@sbi - доступ к собственным элементам массива быстрее, чем к тому же с вектором. Проверено. – Poni

1

Нет, вы не можете инициализировать динамически созданный массив таким же образом.

В большинстве случаев вы обнаружите, что используете динамическое распределение в ситуациях, когда статическая инициализация в действительности не имеет смысла. Например, когда у вас есть массивы, содержащие тысячи элементов. Так что это обычно не имеет большого значения.

8

Вы должны присвоить каждый элемент динамического массива в явном виде (например, в течение или во время цикла)

Однако синтаксис int *p = new int [3](); делает инициализировать все элементы до 0 (инициализации значения $ 8,5/5)

-1

Никогда не слышал о таких вещах, возможно, это было бы неплохо иметь.

Имейте в виду, что при инициализации массива в коде, что путь

int a[] = { 1, 2, 3 }; 

..... только получает вам проще написания кода и не производительность. В конце концов, ЦП будет выполнять работу по присвоению значений массиву, как вы это делаете.

+0

Эта строка не генерирует никакого кода ... это инициализация времени компиляции. – joeking

1

Использование хелперов переменной:

const int p_data[] = {1, 2, 3}; 
int* p = (int*)memcpy(new int[3], p_data, sizeof(p_data)); 

или одна линия

int p_data[] = {1, 2, 3}, *p = (int*)memcpy(new int[3], p_data, sizeof(p_data)); 
+3

Как правило (и хорошая привычка вступать), вы не должны динамически выделять объект в вызове функции (то есть вы никогда не должны называть 'new' в аргументе функции). Причина в том, что порядок оценки аргументов функции неуточнен, поэтому вы можете в конечном итоге динамически распределить память, тогда оценка другого аргумента может вызвать исключение, а затем динамически выделяемый объект будет просочиться. [Herb Sutter имеет больше] (http://www.gotw.ca/gotw/056.htm). –

+0

+1 Хотя это немного загадочно и работает только для POD. – fredoverflow

+1

Джеймс Макнеллис, общие правила - это просто общие правила. И у них есть объяснения, чтобы убедиться, что правило соответствует делу. В этом случае все в порядке. – Abyx

4

Чтобы избежать бесконечных push_backs, я обычно инициализировать tr1::array и создать std::vector (или любой другой контейнер зЬй контейнер) из результат;

const std::tr1::array<T, 6> values = {T(1), T(2), T(3), T(4), T(5), T(6)}; 
std::vector <T> vec(values.begin(), values.end()); 

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

Это можно сделать, конечно, без использования tr1::array;

const T values[] = {T(1), T(2), T(3), T(4), T(5), T(6)}; 
std::vector <T> vec(&values[0], &values[sizeof(values)/sizeof(values[0])]); 

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

+0

+1 Отличное решение! – fredoverflow