Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Справочник по С++.doc
Скачиваний:
49
Добавлен:
02.05.2014
Размер:
995.33 Кб
Скачать

R.8.4.1 Агрегат

Агрегатом называется массив или объект типа класс ($$R.9), не имеющий конструкторов ($$R.12.1), частных или защищенных членов ($$R.11), базовых классов ($$R.10) и виртуальных функций ($$R.10.2). Если агрегат инициализируется, то инициализатором должен быть список-инициализаторов, который состоит из заключенного в фигурные скобки списка, разделенного запятыми, инициализаторов для членов агрегата. Инициализаторы идут в возрастающем порядке индексов или членов агрегата. Если агрегат содержит вложенные агрегаты, это правило применяется рекурсивно для членов вложенных агрегатов. Если инициализаторов в списке меньше, чем членов агрегата, то он дополняется нулевыми значениями соответствующих типов. Например, в следующем фрагменте struct S { int a; char* b; int c; } S ss = { 1, "asdf" }; ss.a инициализируется значением 1, ss.b - "asdf", а ss.c - 0. Кроме того, агрегат, являющийся классом, можно инициализировать объектом этого класса или класса, являющегося общим производным от него ($$R.12.8). Фигурные скобки разбираются следующим образом. Если список-инициализаторов начинается левой фигурной скобкой, то список инициализаторов, разделенных запятыми, задает значения членам агрегата, причем считается ошибкой, если инициализаторов больше, чем членов. Иначе, если список-инициализаторов или вложенный агрегат не начинается левой фигурной скобкой, то из списка используется такое число элементов, которое нужно для инициализации членов текущего агрегата; все оставшиеся элементы используются для инициализации членов следующего агрегата, в который вложен текущий агрегат. Например, в определении int x[] = { 1, 3, 5 }; массив x инициализируется как одномерный массив из трех элементов, поскольку размер массива не указан, и приведено три инициализатора. Приведем пример инициализации с полной скобочной структурой. float y[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7}, }; Здесь значения 1, 3, 5 инициализируют первую строку массива y[0], т.е. y[0][0], y[0][1] и y[0][2]. Аналогично, следующие две строки инициализируют y[1] и y[2]. Инициализаторы приведены не полностью, поэтому y[3] инициализируется нулями. Точно такого же результата можно достичь с помощью такой инициализации: float y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7, }; Последний (самый правый) индекс изменяется быстрее всего. В последнем примере инициализатор для y начинается левой фигурной скобкой, но для y[0] скобки не задано, поэтому из списка используется три элемента, также по три последовательных элемента используется для y[1] и y[2]. В следующем примере float y[4][3] = { { 1 }, { 2 }, { 3 }, { 4 } }; инициализируется первый столбец y (который рассматривается как двумерный массив), а остальные столбцы принимают значение 0. Инициализация массива объектов типа класс с помощью конструкторов описывается в $$R.12.6.1. Инициализатор для объединения без конструктора должен быть или отдельным выражением типа объединения, или заключенным в фигурные скобки, инициализатором первого члена объединения, например, union u { int a; char* b; }; u a = { 1 }; u b = a; u c = 1; // ошибка u d = { 0, "asdf" }; // ошибка u e = { "asdf" }; // ошибка Число инициализаторов не должно превышать числа членов или элементов, которые инициализируются. Например, следующая инициализация ошибочна: char cv[4] = { 'a', 's', 'd', 'f', 0 }; // ошибка