Когда помещать функцию C ++ в заголовочный файл - PullRequest
7 голосов
/ 21 марта 2010

Я смотрел на Boost и различные другие библиотеки C ++. Подавляющее большинство Boost реализовано в заголовочных файлах.

Мой вопрос: при каких условиях вы делаете реализацию только для заголовка (например, Boost) или также включаете файл .cpp?

Ответы [ 2 ]

7 голосов
/ 21 марта 2010

Если вы хотите использовать шаблон в другом модуле перевода (то есть в другом исходном файле), вы должны (почти всегда) определить его в заголовочном файле. (Существуют исключения, как указано в комментариях ниже, но ИМХО это хорошее правило.)

То же самое применимо, если вы хотите использовать встроенную функцию из другой единицы перевода.

В противном случае вы должны поместить реализацию в отдельный файл .cpp, чтобы минимизировать зависимости.

3 голосов
/ 21 марта 2010

Понимание этой проблемы - в основном понимание того, как работают модули компиляции C ++. Вещи в заголовочных файлах в основном вставляются в исходный код целого ряда модулей компиляции с помощью операторов #include. Каждый модуль компиляции компилируется в объектный файл, объектные файлы связываются, и вы получаете конфликты из-за того, что этот материал реплицируется повсеместно.

Исключениями являются вещи, которые (по крайней мере, исторически) не попадают в объектный файл, потому что компилятор работает с ними напрямую (например, встроенные функции), и вещи, которые не могут быть скомпилированы в одном модуле, а затем связаны с другим потому что они не полностью определены (шаблоны). Функции шаблонов часто создаются идентично в нескольких блоках компиляции, а у компоновщика есть специальные умения для удаления дубликатов.

Это означает, что разделение интерфейса и реализации на файлы заголовка и тела не очень чистое. Ада имеет более чистое разделение - но более сложный процесс сборки, чтобы компенсировать IIRC. Java просто отбросила отдельные файлы для интерфейса и реализации.

За прошедшие годы линкеры стали намного более изощренными и взяли на себя часть работы компилятора, и многие из этих объяснений в наши дни просто неверны, но основные паттерны остаются. Шаблонные функции и встроенные функции могут (и часто должны) идти в заголовке вместе со всеми вашими общими объявлениями «не генерировать напрямую объектный код». Обычные определения функций не должны быть в заголовочном файле.

...