logo search
volkov / C++ / Бьерн Страуструп-Справочное руководство по С++

R.18.1 Расширения

В этом разделе перечисляются основные расширения языка С, введенные

в С++.

R.18.1.1 Возможности С++, введенные в 1985 г.

Здесь перечисляются возможности, добавленные к С, версией языка

С++ 1985 г.

Можно указывать типы формальных параметров функции ($$R.8.2.5), и они

будут проверяться ($$R.5.2.2). Будет происходить преобразование

типа ($$R.5.2.2). Это есть и в ANSI C.

В выражениях со значениями типа float вычисления могут проходить

с обычной точностью ($$R.3.6.1 и $$R.4.3). Это есть и в ANSI C.

Можно перегружать имена функций; $$R.13.

Можно перегружать операции; $$R.13.4

Возможна реализация вызова функций подстановкой; $$R.7.1.2.

Можно описывать объекты, представляющие данные, со спецификацией

const; $$R.7.1.6. Это есть и в ANSI C.

Можно описывать типа ссылки; $$R.8.2.2 и $$R.8.4.3.

Возможно управление свободной памятью с помощью операций new и

delete; $$R.5.3.3 и $$R.5.3.4.

Введены классы, которые позволяют: скрывать информацию ($$R.11),

проводить инициализацию ($$R.12.1), осуществлять пользовательские

преобразования типа ($$R.12.3) и работать с динамическими типами

с помощью виртуальных функций ($$R.10.2).

Имя класса или перечисления считается именем типа; $$R.9.

Указатель на любой объект c типом, не являющимся const или volatile,

можно присвоить указателю типа void*. Это есть и в ANSI C.

Указатель на функцию можно присваивать указателю типа void*;

$$R.4.6.

Описание внутри блока считается оператором; $$R.6.7.

Можно описывать безымянные объединения; $$R.9.5.

R.18.1.2 Возможности, добавленные в С++ после 1985 г.

Здесь перечисляются основные расширения С++ после 1985 г.:

Класс может иметь более одного прямого базового класса

(множественное наследование); $$R.10.1.

Члены класса могут быть защищенными; $$R.11.

Операции new и delete можно описывать в классе и перегружать;

$$r.5.3.3, $$R.5.3.4, $$R.12.5. Это позволило определенный способ

управления памятью для класса с помощью "присваивания указателю

this" отнести в раздел анахронизмов; $$R.18.3.3.

Можно явно уничтожать объекты; $$R.12.4.

Присваивания и инициализация для класса определены как присваивание и

инициализация по членам; $$R.12.8.

Служебное слово overload стало излишним и отнесено к разделу

анахронизмов; $$R.18.3.

Произвольные выражения разрешены в качестве инициализаторов статических

объектов; $$R.8.4.

Объекты, представляющие данные, могут быть volatile; $$R.7.1.6.

Также и в ANSI C.

Допустимы инициализаторы для статических членов класса; $$R.9.4.

Функции-члены могут быть статическими; $$R.9.4.

Функции-члены могут быть const или volatile; $$R.9.3.1.

Можно явно указать связывание с подпрограммами на других языках;

$$R.7.4.

Можно перегружать операции ->, ->* и ` ; $$R.13.4.

Классы могут быть абстрактными; $$R.10.3.

Для пользовательских типов префиксные и постфиксные операции

различаются.

Шаблоны типов; $$R.14.

Управление особыми ситуациями; $$R.15.

R.18.2 С++ и ANSI C

Вообще язык С++ обладает большими возможностями и налагает меньше

ограничений, чем ANSI C, поэтому большинство конструкций ANSI C

являются законными для С++, причем смысл их не меняется. Исключения

сводится к следующему:

Любая программа на ANSI C, использующая в качестве идентификаторов

следующие служебные слова С++, не является программой на С++; $$R.2.4:

asm catch class delete friend

inline new operator private protected

public template try this virtual

throw

Хотя это считается устаревшем в ANSI C, реализация С может налагать

драконовские ограничения на длину идентификаторов; в реализациях С++

это недопустимо; $$R.2.3.

В С++ функция должна быть описана прежде, чем ее можно вызвать;

$$R.5.2.2.

Описание f(); в С++ означает, что функция f не имеет параметров

($$R.8.2.5), а в С это означает, что f может иметь любое число

параметров любого типа. Такое описание считается устаревшим в ANSI C.

В ANSI C можно несколько раз описать без спецификации extern глобальный

объект данных, в С++ возможно только одно его определение; $$R.3.3

В С++ класс не может иметь тоже имя, что и имя typedef, относящееся

в той же области видимости к другому типу; $$R.9.1.

В ANSI C операнд типа void* можно использовать в правой части

присваивания, а также при инициализации переменной типа указателя на

произвольный тип; в С++ это невозможно $$R.7.1.6.

В ANSI C возможны команды переходов, обходящие инициализацию;

в С++ это невозможно.

В ANSI C по умолчанию глобальный объект типа const подлежит

внешнему связыванию; для С++ это не так; $$R.3.3.

Определения функций в "старом" стиле и вызовы неописанных функций

считаются в С++ анахронизмами, которые не обязательно должны

поддерживаться любой реализацией; $$R.18.3.1. В ANSI C они просто

считаются устаревшими.

В С++ структура (struct) образует область видимости ($$R.3.2);

В ANSI C структура, перечисление или элемент перечисления,

описанные в структуре поднимаются в область видимости самой

структуры.

Присваивание объекту типа перечисления значения, не принадлежащего

перечислению, считается в С++ анахронизмом и не должно поддерживаться

во всех реализациях; $$R.7.2. В ANSI C рекомендуется для таких

присваиваний выдавать предупреждение.

Строки, инициализирующие символьные массивы, не могут быть длиннее

этих массивов; $$R.8.4.2.

Тип символьной константы в С++ есть char ($$R.2.5.2) и int в

ANSI C.

Тип элемента перечисления есть тип этого перечисления в С++ ($$R.7.2)

и тип int в ANSI C.

Кроме того, стандарт ANSI для С допускает значительные различия в

допустимых реализациях языка, что может привести к еще большим расхождениям

между реализациями С++ и С. В частности, в некоторых реализациях С

могут быть допустимы некоторые несовместимые описания. В С++ требуется

совместимость даже для разных единиц трансляции; $$R.3.3.