2013-08-27 12 views
1

Если я создаю файл заголовка, содержащий определение нескольких функций, почему хорошая практика также включает объявления функций внутри одного заголовка? Кажется излишним включать декларации, когда само определение будет достаточным.Объявление функций в заголовке

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

Есть ли конкретный случай, который послужил бы хорошим примером того, как он используется?

+0

«вы не можете использовать объявление в другом файле отдельно и использовать эту функцию». Вы полностью можете, и это _exactly_, для каких деклараций. –

ответ

5

Как правило, неправильно помещать определение функции в файл заголовка, поскольку включение файла в несколько источников приведет к нескольким определениям. Это нормально, если функция объявлена ​​как статическая или встроенная, либо является частью шаблона.

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

+0

Как вы связываете исходный файл, содержащий определение, и файл заголовка с объявлением? – Ares

+2

@Comrade, как правило, исходный файл и заголовочный файл имеют одинаковое имя; вы '# включаете' заголовочный файл и компилируете исходный файл и объединяете его с помощью компоновщика. Часто компоновщик вызывается автоматически, поэтому вы его даже не замечаете. –

+0

Если исходный файл и заголовочный файл имеют разные имена, компоновщик должен быть вызван вручную? Как это называется? – Ares

1

Если я создаю файл заголовка, содержащий определение нескольких функций,

прекратить делать это.

Почему хорошая практика включает также объявления функций внутри одного заголовка?

Это не так. Только помещают объявления в заголовок, а только помещают определения в соответствующий файл .cpp.

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

+1

Или если вы пишете класс шаблона, так как я еще не видел компилятор, который может обрабатывать объявления шаблонов обработки и определения в отдельных файлах правильно. –

0

Для людей, читающих файл заголовка, им может быть легче увидеть все объявления в одном месте, не прочитав их.

Сказать, что я не уверен, что необходимо направить объявить функцию в том же заголовке и в шаблонных классах, которые я видел (как повышение :: scoped_ptr) люди не утруждают вперед объявлять функции

2

Как правило, вы помещаете свои объявления в файл заголовка и свое определение в файл реализации. Существует несколько причин для этого:

1) Он улучшает читаемость и предоставляет «список функций» для всех, кто может читать ваш код.

2) Если вам случится с продуктом библиотеки, вы можете просто отправить файл заголовка и двоичный файл библиотеки, не выпуская полный исходный код.

3) Если вам нужно реализовать реализации, зависящие от платформы, вы можете иметь другую реализацию, которая скомпилируется для одного и того же заголовка.

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

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

1

Одним из важных аспектов, не упомянутых в других ответах, является скорость компиляции: каждый раз, когда определение функции рассматривается компилятором, оно должно генерировать код для него, даже если этот код не нужен в данной единицы перевода и избыточности , поскольку компилятор не может знать, что другой блок компиляции фактически предоставит скомпилированную функцию.

Большинство файлов заголовков скомпилированы два-десять раз, поэтому определение функции в заголовке замедляет компиляцию этой функции тем же самым фактором.

Возможно, вы не найдете это важным, потому что ваш проект небольшой, но он становится важным с крупными проектами, так как он может сильно повлиять на процесс change-compile-test-cycle. Это одна из главных причин, по которой компиляция программы на C гораздо меньше времени, чем компиляция эквивалентной программы на C++.

Смежные вопросы