R.8.4 Инициализаторы
R.8.4 Инициализаторы
За описателем может идти начальное значение описываемого идентификатора.
инициализатор:
= выражение-присваивания
= { список-инициализаторов , opt }
( список-выражений )
список-инициализаторов:
выражение-присваивания
список-инициализаторов, выражение-присваивания
{ список-инициализаторов , opt }
Автоматические, регистровые, статические и внешние переменные можно инициализировать произвольными выражениями, содержащими константы и описанные ранее переменные и функции.
int f(int);
int a = 2;
int b = f(a);
int c(b);
Указатель типа const T*, т.е. указатель на константу T, может инициализироваться указателем типа T*, но инициализация для указателей в обратном порядке незаконна. Объекты типа T можно инициализировать объектами типа T независимо от использования спецификаций const или volatile в типах инициализируемой переменной или инициализатора, например,
int a;
const int b = a;
int c = b;
const int* p0 = &a;
const int* p1 =&b;
int* p2 = &b; // ошибка: указатель без const
// настраивается на объект const
int *const p3 = p2;
int *const p4 = p1; // ошибка: указатель без const
// настраивается на объект const
const int* p5 = p1;
Здесь причина обеих ошибок одна: если допустить подобную инициализацию, она позволит изменять с помощью указателя без соответствующей спецификации значение чего-то, что было описано как const.
На выражения для стандартных значений параметров накладывается больше ограничений, см. §R.8.2.6.
Инициализация объектов классов с помощью конструкторов описывается в §R.12.6.1. Копирование объектов классов описывается в §R.12.8. Порядок инициализации статических объектов определяется в §R.3.4 и §R.6.7.
Гарантируется, что переменные статического класса памяти (§R.3.5), которые не были инициализированы, в качестве начального значения получат 0, приведенный к нужному типу. То же справедливо для статических членов объектов класса. Начальные значения автоматических и регистровых переменных, которые не были инициализированы, неопределены.
Если инициализатор относится к указателю или объекту арифметического типа, он состоит из одного выражения (возможно в скобках). В качестве начального значения объекта берется значение выражения, происходят такие же преобразования типа, как и в случае присваивания.
Заметим, что поскольку () не является инициализатором, описание
X a();
задает не объект a типа класс X, а является описанием функции без параметров, возвращающей X.
Инициализатор для статического члена принадлежит области видимости члена класса, например,
int a;
struct X {
static int a;
static int b;
};
int X::a = 1;
int X::b = a; // X::b = X::a