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

R.7.1.2 Спецификации функций

Некоторые спецификации можно использовать только в описании функций. спецификация-fct: inline virtual Спецификация inline подсказывает транслятору, что необходимо произвести подстановку тела функции вместо обычной реализации вызова функции. Подсказка может игнорироваться. В случае функций, не являющихся членами, спецификация inline дополнительно устанавливает для функции внутреннее связывание ($$R.3.3). Функция ($$R.5.2.2, $$R.8.2.5), определенная в описании класса, имеет по умолчанию спецификацию inline. Функция-член со спецификацией inline должна иметь в точности такое же определение в каждой единице трансляции, где она появляется. Функцию-член не обязательно явно описывать со спецификацией inline при описании класса, чтобы она трактовалась как подстановка. Если спецификации inline не было, связывание будет внешним, если только определение со спецификацией inline не появится перед первым вызовом функции. class X { public: int f(); inline int g(); // X::g() имеет внутреннее связывание int h(); }; void k(X* p) { int i = p->f(); // теперь X::f() внешнее связывание int j = p->g(); // ... } inline int X::f() // ошибка: вызов до определения // как inline { // ... } inline int X::g() { // ... } inline int X::h() // теперь X::h() имеет внутреннее связывание { // ... } Спецификация virtual может использоваться только в описаниях нестатических функций-членов при описании класса (см. $$R.10.2).

R.7.1.3 Спецификация typedef

Описания со спецификацией typedef задают идентификаторы, которые позднее могут использоваться для обозначения основных или производных типов. Спецификация typedef недопустима в определении-функции ($$R.8.3). имя-typedef: идентификатор В пределах области видимости ($$R.3.2) описания typedef любой идентификатор, появляющийся в части любого из описателей, становится синтаксически эквивалентным служебному слову и обозначает тип, связанный с данным идентификатором, как описано в $$R.8. Таким образом, имя-typedef является синонимом другого типа. В отличие от описания класса ($$R.9.1) имя-typedef не добавляет нового типа. Например, после описания typedef int MILES, *KLICKSP; конструкции MILES distance; extern KLICKSP metricp; являются законными описаниями, тип distance есть int, а у metricp тип "указатель на int". С помощью typedef можно переопределить имя так, чтобы оно опять обозначало тип, на который уже ссылалось, причем даже в той области видимости, в которой тип был первоначально описан, например, typedef struct s { /* ... */ } s; typedef int I; typedef int I; typedef I I; Безымянный класс, который определяется в typedef, получает в качестве своего имени имя, использованное в typedef, например, typedef struct { /* .... */ } S; // имя структуры стало S С помощью описания typedef нельзя переопределить имя типа, описанного в этой же области видимости, так, чтобы оно обозначало другой тип, например, class complex { /* ... */ }; typedef int complex; // ошибка: переопределение Аналогично, нельзя описывать класс с именем типа, описанного в этой же области видимости, так, чтобы он обозначал другой тип, например, typedef int complex; class complex { /* ... */ }; // ошибка: переопределение Имя-typedef, которое обозначает класс, является именем-класса ($$R.9.1). Синоним нельзя использовать после следующих префиксов: class, struct и union, а также в именах конструкторов и деструкторов в описании самого класса, например, struct S { S(); ~S(); }; typedef struct S T; S a = T(); // нормально struct T* p; // ошибка