C++
Шрифт:
8.5.14 Поля бит
Описатель_члена вида
идентификатор opt : константное_выражение
определяет поле; его длина отделяется от имени поля дветочием. Поля упаковываются в машинные целые; они не являются альтернативой слов. Поле , не влезающее в оставшееся в целом место, помещается в следующее слово. Поле не может быть шире слова. На некоторых машинах они размещаются справа налево, а на некоторых слева направо, см. #2.6.
Неименованные поля полезны при заполнении для согласовния внешне предписанных размещений (форматов). В особых слчаях неименованные
Поля не могут быть членами объединения.
8.5.15 Вложенные классы
Класс может быть описан внутри другого класса. Это, онако, лишь соглашение о записи, поскольку внутренний класс принадлежит охватывающей области видимости. Например:
int x;
class enclose (* // охватывающий int x; class inner (* // внутренний int y; void f(int); *); int g(inner*); *);
inner a; void inner::f(int i) (* x = i; *) // присваивает ::x int enclose::g(inner* p) (* return p-»y; *) // ошибка
8.6 Инициализация
Описатель может задавать начальное значение описываемого идентификатора.
инициализатор: = выражение = (* список_инициализаторов , opt *) ( список_выражений ) список_инициализаторов: выражение список_инициализаторов , список_инициализаторов (* список_инициализаторов *)
Все выражения в инициализаторе статической или внешней переменной должны быть константными выражениями, которые опсаны в #12, или выражениями, которые сводятся к адресам ранее описанных переменных, возможно со смещением на константное выражение. Автоматические и регистровые переменные могут инциализироваться любыми выражениями, включащими константы, рнее описанные переменные и функции.
Гарантируется, что неинициализированные статические и внешние переменные получают в качестве начального значения 0. Гарантируется, что неинициализированные автоматические и ргистровые переменные получают в качестве начального значения «пустое место»*.
– * В английском – «garbage», означающее затертое место [памяти], т.е. если переменная целая, то 0, если char, то '\0', если указатель на Т, то (Т*) NULL. (прим. перев.)
Когда инициализатор применяется к скаляру (указатель или объект арифметического типа), он состоит из одного выражения, возможно, заключенного в фигурные скобки. Начальное значение объекта находится из выражения; выполняются те же преобразвания, что и при присваивании.
Заметьте, что поскольку не является инициализатором, то X a; является не описанием объекта класса X, а описанием функции, не получающей значений и возвращающей X.
8.6.1 Список инициализаторов
Когда описанная переменная является составной (класс или массив), то инициализатор может состоять из заключенного в фигурные скобки, разделенного запятыми списка инициализаторов для членов составного
Фигурные скобки могут опускаться следующим образом. Если инициализатор начинается с левой фигурной скобки, то следущий за ней список инициализаторов инициализирует члены сотавного объекта; наличие числа инициализаторов, большего, чем число членов, считается ошибочным. Если, однако, инициализтор не начинается с левой фигурной скобки, то из списка брутся только элементы, достаточные для сопоставления элеметам составного объекта; все остающиеся элементы оставляются для инициализации следующего элемента составного объекта, частью которого является текущий составной объект.
Например,
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] инициализируется 0-ями. В тоноcти тот же эффект может быть достигнут с помощью
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 (рассматриваемого как двумерный массив) и оставляет остальные элементы нулями.
8.6.2 Объекты классов
Объект с закрытыми членами не может быть инициализован списком инициализаторов; это же относится к объекту объединние. Объект класса с конструктором должен инициализироваться. Если класс имеет конструктор, не получающий параметров, то этот конструктор используется для объектов, которые явно не инициализированы. Список параметров для конструктора можно добавлять к имени в описании или к типу в выражении new. Слдующие инициализации все дают одно и тоже значение (#8.4): struct complex (*
float re; float im; complex (float r,float i = 0) (* re=r; im=i; *) *);
complex zz1(1,0); complex zz2(1); complex* zp1 = new complex (1,0); complex* zp1 = new complex (1);
Объекты класса могут также инициализироваться с помощью явного использования операции =. Например:
complex zz3 = complex (1,0); complex zz4 = complex (1); complex zz5 = 1; complex zz6 = zz3;
Если есть конструктор, получающий ссылку на объект свого собственного класса, то он будет вызываться при инициалзации объекта другим объектом этого класса, но не при иницилизации объекта конструктором.