7.4 C++ Интерфейсы и реализации псевдокоманд
#pragma interface и #pragma implementation предоставляют пользователю способ явно указать компилятору на необходимость генерации сущностей с неясной связью (и отладочной информацией) в конкретной единице трансляции.
Примечание: Эти #pragma были заменены поддержкой COMDAT и эвристикой «ключевой метод», упомянутой в Неясной связи, начиная с GCC 2.7.2. Их использование может фактически увеличить размер вашей программы из-за ненужных копий внестрочных функций.
#pragma interface#pragma interface "subdir/objects.h"-
Используйте эту директиву в заголовочных файлах, определяющих классы объектов, для экономии места в большинстве объектных файлов, использующих эти классы. Обычно локальные копии определённой информации (резервные копии встраиваемых функций-членов, отладочной информации и внутренних таблиц, реализующих виртуальные функции) должны храниться в каждом объектном файле, включающем определения классов. Вы можете использовать эту псевдокоманду, чтобы избежать такой дублирования. При включении заголовочного файла, содержащего ‘#pragma interface’, в компиляцию, эта вспомогательная информация не генерируется (если только сам основной входной исходный файл не использует ‘#pragma implementation’). Вместо этого объектные файлы содержат ссылки, которые должны быть разрешены во время компоновки.
Вторая форма этой директивы полезна в случае, когда у вас есть несколько заголовочных файлов с одинаковым именем в разных каталогах. Если вы используете эту форму, вы должны указать ту же строку в ‘#pragma implementation’.
#pragma implementation#pragma implementation "objects.h"-
Используйте эту псевдокоманду в основном входном файле, когда вы хотите получить полную информацию из включённых заголовочных файлов (и сделать её глобально видимой). Включённый заголовочный файл, в свою очередь, должен использовать ‘#pragma interface’. Резервные копии встраиваемых функций-членов, отладочной информации и внутренних таблиц, используемых для реализации виртуальных функций, генерируются в файлах реализации.
Если вы используете ‘#pragma implementation’ без аргумента, она применяется к файлу включения с тем же базовым именем4, что и ваш исходный файл. Например, в файле allclass.cc, использование только ‘#pragma implementation’ эквивалентно ‘#pragma implementation "allclass.h"’.
Используйте строковый аргумент, если вы хотите, чтобы один файл реализации включал код из нескольких заголовочных файлов. (Вы также должны использовать ‘#include’ для включения заголовочного файла; ‘#pragma implementation’ только определяет, как использовать файл — он не включает его фактически.)
Нет способа разделить содержимое одного заголовочного файла на несколько файлов реализации.
‘#pragma implementation’ и ‘#pragma interface’ также влияют на встраивание функций.
Если вы определяете класс в заголовочном файле, помеченном ‘#pragma interface’, влияние на встраиваемую функцию, определённую в этом классе, аналогично явному extern объявлению — компилятор вообще не генерирует код для определения независимой версии функции. Его определение используется только для встраивания в вызывающие её функции.
И наоборот, при включении того же заголовочного файла в основной исходный файл, объявленный как ‘#pragma implementation’, компилятор генерирует код для самой функции; это определяет версию функции, которая может быть найдена через указатели (или вызывающими функциями, скомпилированными без встраивания). Если все вызовы функции могут быть встроены, вы можете избежать генерации функции, скомпилировав с -fno-implement-inlines. Если какие-либо вызовы не могут быть встроены, у вас появятся ошибки компоновщика.
Примечания
Базовое имя файла — это имя, из которого удалены вся информация о пути и все суффиксы, такие как ‘.h’ или ‘.C’ или ‘.cc’.
Далее: Шаблонная инициализация, Предыдущий: Неясная связь, Вверх: Расширения C++ [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/gcc/C_002b_002b-Interface.html