Практические правила размещения функций в заголовочных файлах

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

Каковы ваши практические правила для перемещения функций из или в заголовочные файлы?

Если вам интересно, я говорю о разработке приложений, а не библиотек.

Редактировать:

Полагаю, это полезно, если я нарисую плюсы / минусы встроенных (естественно) функций заголовка по сравнению с функциями реализации с моей точки зрения:

Про встроенный:

  • Более чистый / лаконичный.
  • Нет необходимости дублирования подписи.
  • Нет необходимости изменять какой-либо Makefile для связи с новыми файлами.
  • Мгновенная возможность ввести параметры шаблона.

Contra inline:

  • Увеличенное время компиляции (мне все равно)
  • Многие включают в заголовки (не должно быть такой большой проблемой, если они используют охрану)

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

7 ответов

Решение

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

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

Мое эмпирическое правило: "Не в заголовке, если нет необходимости". А что касается удобства, считаете ли вы удобным увеличение времени компиляции?

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

Итак, вопрос сводится к:

встроенный в заголовке и вне строки в файле реализации?

Факторы:

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

Итог: если вы обнаруживаете, что делаете это все больше и больше, тогда это, очевидно, работает на вас, и нет особой причины думать, что вас вот-вот обожгут. Следите за потенциальными проблемами, но не переусердствуйте, черт возьми, из материала, основанного на некоторой гипотетической и маловероятной проблеме.

Я использую два правила:

1) Если это встроенные функции

2) Если это шаблонная функция.

Во-первых, функция шаблона должна быть помещена в заголовки.

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

Я никогда не пользуюсь inline потому что компилятор не гарантирует этого.

Хороший стандарт кодирования скажет вам реализовать методы и функции в исходном (cpp) файле.

Если вы предпочитаете это, вы можете реализовать шаблоны и встроенные функции в заголовке.

Так как это было помечено как C++почему бы вам не разделить их на логические classэс?

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

Другие вопросы по тегам