Страустрап Бьярн
Шрифт:
• Нельзя пользоваться специфическими возможностями C++ такими, как классы, перегрузка и т.п.
• Нельзя использовать одно имя для обозначения типа структуры и другого типа.
• Функцию без параметров следует описывать как f(void), а не просто f.
• Глобальные объекты типа const следует явно специфицировать как static или extern.
• Для разделения частей программы на ANSI C и C++ можно использовать условную трансляцию с предописанным именем __cplusplus.
• Функции, которые могут вызываться из программ на обеих языках, должны быть явно описаны, как функции, подлежащие связыванию с С.
R.18.3 Анахронизм
Реализация C++ может включать перечисленные здесь расширения, чтобы облегчить использование программы на С, или чтобы упростить переход с более ранних версий С++. Отметим, что с каждым расширением связаны нежелательные последствия. Если реализация предоставляет такое расширение, то она должно также предоставлять возможность убедиться в отсутствии этих последствий для исходной программы. Реализация C++ не обязана обеспечивать эти расширения.
• При описании или определении функции можно использовать слово overload в конструкции спецификация-описания (§R.7). Если оно используется в спецификации-описания, то считается служебным словом и его нельзя использовать как идентификатор.
• Определение статического члена класса, представляющего данные, для которого дана стандартная инициализация нулями (§R.8.4, §R.9.4), может быть опущено.
• Можно использовать команды препроцессора старого стиля (до ANSI C).
• Можно присваивать объекту типа перечисления значение типа int.
• При удалении массива, тип которого не имеет деструктора, можно указывать число элементов; §R.5.3.4.
• Одна функция operator++ может использоваться для перегрузки как префиксных, так и постфиксных операций ++; тоже верно для операции --; §R.13.4.6.
R.18.3.1 Определения функций старого стиля
Можно использовать синтаксис С для определений функций:
Приведем пример:
Если определенная таким образом функция не была описана ранее, то тип ее формальных параметров полагается (…), т.е. он не будет проверяться.
Если она была описана, то тип должен согласовываться с типом, указанным в описании.
Приведенный синтаксис нельзя использовать для определения функций-членов.
R.18.3.2 Старый стиль задания инициализатора базового класса
В конструкции инициализатор-памяти (§R.12.6.2) можно не указывать имя-класса, обозначающее базовый класс при условии, что существует только один прямой (непосредственный) базовый класс. Поэтому в описании
будет вызываться конструктор B с параметром i.
R.18.3.3 Присваивание указателю this
Присваивая определенные значения указателю this, пользователь мог управлять выделением памяти для объекта некоторого класса. В конструкторе до использования членов класса можно было с помощью такого присваивания реализовать свой алгоритм выделения памяти. Присваивая в деструкторе указателю this нуль, можно было обойти стандартную операцию освобождения объектов класса. Кроме того, присваивание нуля в деструкторе отменяло неявные вызовы деструкторов для членов и базовых классов, например:
Если выделение памяти уже произошло (как бывает для членов и объектов auto или static), то при входе в конструктор this имеет ненулевое значение и значение нуль в противном случае.
Вызовы конструкторов для членов и базовых классов произойдут только после того, как this получил значение. Если в конструкторе базового класса есть присваивание this, то новое значение this будет использоваться и в конструкторах производных классов, если они есть.