C ++ Как установить массив указателей на нуль в списке инициализаторов, как? - PullRequest
25 голосов
/ 11 апреля 2010

Я знаю, что вы не можете использовать список инициализаторов для массива. Однако я слышал о способах, которыми вы можете установить массив указателей на NULL способом, подобным списку инициализатора.

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

Редактировать: я имею в виду сделать это в списке инициализации файла заголовка / конструктора. Я не хочу помещать это в конструктор, и я не хочу использовать Вектор.

Ответы [ 6 ]

36 голосов
/ 11 апреля 2010

Чтобы установить массив указателей на нули в списке инициализатора конструктора, вы можете использовать () initializer

struct S {
  int *a[100];

  S() : a() {
    // `a` contains null pointers 
  }
};

К сожалению, в текущей версии языка инициализатор () является единственным инициализатором, который вы можете использовать с элементом массива в списке инициализатора конструктора. Но, видимо, это то, что вам нужно в вашем случае.

() оказывает тот же эффект на массивы, выделенные с new[]

int **a = new int*[100]();
// `a[i]` contain null pointers 

В других контекстах вы можете использовать {} агрегатный инициализатор для достижения того же эффекта

int *a[100] = {};
// `a` contains null pointers 

Обратите внимание, что абсолютно не нужно сжимать 0 или NULL между {}. Пустая пара {} отлично подойдет.

6 голосов
/ 11 апреля 2010

Вы можете переключиться с массива на std::vector и использовать

std::vector<T*> v(SIZE);

Значения будут инициализированы NULL с автоматически. Это предпочтительный способ C ++.


Обновление: начиная с C ++ 11, есть еще один способ: использование

std::array<T*, SIZE> array = {};

Это ведет себя больше как исправленная версия массива в стиле C (в частности, избегает динамического выделения), переносит его размер и не затухает до указателя. Размер, однако, должен быть известен во время компиляции.

4 голосов
/ 11 апреля 2010

Обычно массив не инициализируется по умолчанию, но если вы инициализируете один или несколько элементов явно, то любые оставшиеся элементы будут автоматически инициализированы равными 0. Поскольку 0 и NULL эквивалентны, вы можете инициализировать массив указателей на NULL как это:

float * foo[42] = { NULL }; // init array of pointers to NULL
2 голосов
/ 11 апреля 2010

Я не уверен, как это сделать. Я слышал, что указатель по умолчанию установлен в NULL, хотя я не знаю, гарантировано ли это / в стандарте C ++.
Это не гарантируется стандартом C ++. Встроенные типы (например, указатели) заполняются мусором, если не указано иное.

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

MyType * pointers[2] = {}

и указатели должны быть инициализированы как NULL.

0 голосов
/ 11 апреля 2010

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

Тем не менее, есть вероятность, что вам действительно лучше использовать std::vector. За исключением технических причин, таких как недоступность стандартного STL для вашей платформы или немного меньшая производительность, std::vector лучше массива по всем критериям. Если проблема заключается в производительности, убедитесь, что вы выполнили профилирование и знаете по номерам, что это проблема.

0 голосов
/ 11 апреля 2010
void* p[10] = { 0 };
...