Имена типов
Иногда (для неявного задания преобразования типов и в качестве параметра sizeof или new) нужно использовать имя типа данных. Это выполняется при помощи "имени типа" которое по сути является описанием для объекта этого типа, в котором опущено имя объекта.
имя_типа: спецификатор_типа абстрактный_описатель абстрактный_описатель : пустой * абстрактный_описатель абстрактный_описатель ( списоко_писателей_параметров) абстрактный_описатель [ константное_выражение opt ] ( абстрактный_описатель )
Является возможным идентифицировать положение в абстрактном_описателе, где должен был бы появляться идентификатор в случае, если бы конструкция была описателем в описании. Тогда именованный тип является тем же, что и тип предполагаемого идентификатора. Например:
int int * int *[3] int *() int (*)()
именует, соответственно, типы "целое", "указатель на целое", "указатель на массив из трех целых", "функция, возвращающая указатель на функцию, возвращающую целое" и "указатель на целое".
Простое имя типа есть имя типа, состоящее из одного идентификатора или ключевого слова.
простое_имя_типа: typedef-имя char short int long unsigned float double
Они используются в альтернативном синтаксисе для преобразования типов. Например:
(double) a
может быть также записано как
double (a)
Определение типа typedef
Описания, содержащие спецификатор_описания typedef, определяют идентификаторы, которые позднее могут использоваться так, как если бы они были ключевыми словами типа, именующее основные или производные типы.
typedef-имя: идентификатор
Внутри области видимости описания, содержащего 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 matrix operator* (matrix&,vector&); };
class vector { ... friend matrix operator* (matrix&,vector&); };
Перегруженные имена функций
В тех случаях, когда для одного имени определено несколько (различных) описаний функций, это имя называется перегруженным. При использовании этого имени правильная функция выбирается с помощью сравнения типов фактических параметров с типами параметров в описаниях функций. К перегруженным именам неприменима операция получения адреса &.
Из обычных арифметических преобразований, определенных в этом пункте, для вызова перегруженной функции выполняются только char->short->int, int->double, int->long и float->double. Для того, чтобы перегрузить имя функции не-члена описание overload должно предшествовать любому описанию функции; см. здесь.
Например:
overload abs; int abs (int); double abs (double);
Когда вызывается перегруженное имя, по порядку производится сканирование списка функций для нахождения той, которая может быть вызвана. Например, abs(12) вызывает abs(int), а abs(12.0) будет вызывать abs(double). Если бы был зарезервирован порядок вызова, то оба обращения вызвали бы abs(double).
Если в случае вызова перегруженного имени с помощью вышеуказанного метода не найдено ни одной функции, и если функция получает параметр типа класса, то конструкторы классов параметров (в этом случае существует единственный набор преобразований, делающий вызов допустимым) применяются неявным образом. Например:
class X { ... X (int); }; class Y { ... Y (int); }; class Z { ... Z (char*); };
overload int f (X), f (Y); overload int g (X), g (Y);
f (1); /* неверно: неоднозначность f(X(1)) или f(Y(1)) */ g (1); /* g(X(1)) */ g ("asdf"); /* g(Z("asdf")) */
Все имена функций операций являются автоматически перегруженными.
Описание перечисления
Перечисления являются int с именованными константами.
enum_спецификатор: enum идентификатор opt { enum_список }
enum_список: перечислитель enum_список, перечислитель
перечислитель: идентификатор идентификатор = константное_выражение
Идентификаторы в enum-списке описаны как константы и могут появляться во всех местах, где требуются константы. Если не появляется ни одного перечислителя с =, то значения всех соответствующих констант начинаются с 0 и возрастают на 1 по мере чтения описания слева направо. Перечислитель с = дает ассоциированному с ним идентификатору указанное значение; последующие идентификаторы продолжают прогрессию от присвоеннного значения.
Имена перечислителей должны быть отличными от имен обычных переменных. Значения перечислителей не обязательно должны быть различными.
Роль идентификатора в спецификаторе перечисления enum_спецификатор полностью аналогична роли имени класса; он именует определенный нутератор. Например:
enum color { chartreuse, burgundy, claret=20, winedark }; ... color *cp, col; ... col = claret; cp = &col; ... if (*cp == burgundy) ...
делает color именем типа, описывающего различные цвета, и затем описывает cp как указатель на объект этого типа. Возможные значения извлекаются из множества { 0, 1, 20, 21 }.
Описание Asм
Описание Asm имеет вид <ыpre> asm (строка);
Смысл описания asm не определен. Обычно оно используется для передачи информации ассемблеру через компилятор.
1 2 3 4 5 6
8 8 8
|