Когда переменная описана как T amp;, то есть «ссылка на тип T», она должна быть инициализирована или объектом типа T, или объектом объектом, который может быть преобразован в T. Ссыка становится другим именем объекта. Например:
int i; int amp; r = i; r = 1; // значение i становится 1 int* p = amp;r; // p указывает на i
Значение ссылки не может быть изменено после инициализции. Заметьте, что обработка инициализации ссылки очень силно зависит от того, что ей присваивается. Если инициализатор для ссылки на тип T не является lvalue, то будет создан и инициализован инициализатором обект типа T. Тогда ссылка станет именем для этого объекта. Время жизни объекта, созданного таким способом, будет область видимости, в которой он создан. Например:
double amp; rr = 1;
допустимо, и rr будет указывать на объект типа double, содержащий значение 1.0.
Заметьте, что ссылка на класс B может быть инициализирвана объектом класса D при условии, что B является открытым базовым классом класса D (в этом случае D есть B).
Ссылки особенно полезны в качестве типов параметров. Например:
struct B (* ... *); struct D : B (* ... *); int f(B amp;); D a; f(a);
8.6.4 Массивы Символов
Массив char можно инициализировать строкой. Последовтельные символы строки инициализируют члены массива. Напрмер:
char msg[] = «Syntax error on line %d\n»;
демонстрирует массив символов, члены которого инициалзированы строкой. Обратите внимание, что sizeof(msg)==25.
8.7 Имена Типов
Иногда (для неявного задания преобразования типов и в качестве параметра sizeof или new) нужно использовать имя тпа данных. Это выполняется при помощи «имени типа» которое по сути является описанием для объекта этого типа, в котором опущено имя объекта.
имя_типа: спецификатор_типа абстрактный_описатель
абстрактный_описатель: пустой * абстрактный_описатель абстрактный_описатель ( списоко_писателей_параметров) абстрактный_описатель [ константное_выражение opt ] ( абстрактный_описатель )
Возможно единственным образом идентифицировать положение в абстрактном_описателе, где должен стоять идентификатор в случае, если бы конструкция была описателем в описании. Тогда именованный тип является – тот же, что и тип гипотетического идентификатора. Например,
int int * int *[3] int (*)[3] int *() int (*)()
именуют, соответсвенно, типы «целое», «указатель на цлое», «массив из 3 указателей на целые», «указатель на массив из 3 целых», «функция, возвращающая указатель на целое» и «указатель на функцию, возвращающую целое».
8.8 Typedef – Определение Типа
Описания, содержащие спецификатор_описания typedef, определяют идентификаторы, которы позднее могут использоваться так, как если бы они были ключевыми словами, именующими оновные или производные типы.
typedef-имя: идентификатор
Внутри области видимости описания, содержащего typedef, каждый идентификатор, возникающий как часть какого-либо опсателя, становится в этом месте синтаксически эквивалентным ключевому слову типа, которое именует тип, ассоциированный с идентификатором таким обрахом, как описывается в #8.4. Спецфикатор_описания typedef не может использоваться для члена класса. Имя класса или перечисления также является typedef-именем. Например, после
typedef int MILES, *KLICKSP; struct complex (* double re, im; *);
каждая из конструкций
MILES distance; extern KLICKSP metricp; complex z, *zp;
является допустимым описанием; distance имеет тип int, metricp имеет тип «указатель на int».
typedef вводит не новые типы, но только синонимы для тпов, которые могли бы быть определены другим путем. Так в приведенном выше примере distance рассматривается как имеющая в точности тот же тип, что и любой другой int объект.
Но описание класса вводит новый тип. Например:
struct X (* int a; *); struct Y (* int a; *); X a1; Y a2; int a3;
описывает три переменных трех различных типов.
Описание вида
описание_имени: сост идентификатор ; enum идентификатор ;
специфицирует, что идентификатор является именем некотрого (возможно, еще не определенного) класса или перечислния. Такие описания позволяют описывать классы, ссылающихся друг на друга. Например:
class vector;
class matrix (* // ... friend vector operator*(matrix amp;, vector amp;); *);
class vector (* // ... friend matrix operator*(matrix amp;, vector amp;); *);
8.9 Перегруженные Имена Функций
В тех случаях, когда для одного имени определено неколько (различных) описаний функций, это имя называется прегруженным. При использовании этого имени правильная функция выбирается с помощью сравнения типов фактических параметров с типами формальных параметров в описаниях функций.
Поиск того, какую функцию вызвать, осуществляется в три отдельных шага:
Искать точно соответствующую и использовать, если найдна.
Искать соответствующую с использованием стандартных пробразований (#6.6-8) и использовать любую найденную.
Искать соответствующую с использованием определенных пользователем преобразований (#6.5.6). Если найдено единтвенное множество преобразований, использовать ее.