Поведение списка инициализаторов для массива структур

Я просмотрел несколько книг по С ++, но ни одна из них не описывает это подробно:

С VC ++ 2010 я создал структуру с намеренно добавленными для тестирования конструкторами:

struct BufferElement {
size_t currentAllocationSize;
BufferElement() {
currentAllocationSize=50;
}
BufferElement(size_t size) {
if (size==0)
currentAllocationSize=20;
else
currentAllocationSize=1;
}
};

И у меня есть массив этого типа структуры:

int _tmain(int argc, _TCHAR* argv[])
{
BufferElement buffers[10]={0};
buffers[6]=0;
for (int i=0; i<sizeof buffers/ sizeof buffers[0]; i++) {
printf("%d\n", buffers[i].currentAllocationSize);
}

return 0;
}

Результат:

20
50
50
50
50
50
20
50
50
50

Я ожидаю, что мой список инициализатора массива {0} должен инициализировать все элементы равными 0. Поскольку это массив struct, 0 должен означать вызов конструктора с 0. Но тест показывает, что, кроме первого элемента, все они вызываются конструктором по умолчанию. Это стандартное поведение? Как мне интерпретировать инициализатор массива {0}, если тип массива — структура? Как сделать так, чтобы вместо этого вызывался мой конструктор arg без использования {0,0,0,0,0,0,0,0,0,0}? Так как мой размер массива может измениться.

1

Решение

Вы указываете значение только для первого элемента, поэтому один элемент будет инициализирован с помощью BufferElement(your-value), Остальным элементам не указано значение, поэтому они будут использовать конструктор по умолчанию. Вот что происходит для классов и структур.

В массивах встроенных типов, таких как intостальные значения вместо этого будут Значение инициализирован, что делает их ноль. Не так для объектов класса.

1

Другие решения

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

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

1

Инициализация всех элементов массива путем предоставления только одного значения ({0}) не требуется стандартом. Так как это массив structs, их конструкторы по умолчанию вызываются для их инициализации.

Если вы хотите инициализировать их все определенным значением, вы должны перечислить все элементы, например: {0, 0, 0, 0, ..., 0},

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

std::vector<BufferElement> vec(10, BufferElement(0));
1

Да, именно так и должно быть.

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

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

BufferElement buffers[10];

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

(не проверено, должно работать)

#include <vector>
#include <algorithm>
using namespace std;

// ...

vector<BufferElement> buffers;
buffers.fill_n(10,0);
1