Что я должен учитывать при помещении всего кода в заголовок?

Я нашел несколько мест, где обсуждается, лучше ли помещать определения в заголовки или нет (например, Вот). Тем не менее, я не смог найти что-то вроде «руководства по коду только для заголовка». В ответе на связанный вопрос упоминаются некоторые недостатки:

  • увеличено время компиляции
  • невозможно иметь круговые зависимости
  • нет (простых) глобальных объектов

Но это все?

Каковы последствия размещения (всего) кода в заголовке?

Я спасу, если я использую охрану заголовка, или есть другие подводные камни?

Я спрашиваю об этом по следующей причине:
Я нахожусь в ситуации, когда я думаю, что было бы проще всего поместить весь код в мои заголовочные файлы. Это (довольно небольшая) коллекция классов и функций, которая должна быть включена другими в их код. Предполагается, что он будет использоваться в разных средах и в разных средах. В настоящий момент я не понимаю, почему я должен встраивать свой код (в библиотеку), когда тот, кто его использует, может просто включить нужный ему заголовок и скомпилировать его. Однако, независимо от этого проекта, я всегда испытываю «дурное предчувствие», когда помещаю код в заголовки, даже если ни один из трех упомянутых выше пунктов не имеет значения. Было бы очень хорошо, если бы кто-то мог пролить свет на это для меня, чтобы я мог принять решение, где разместить код на более разумной основе.

2

Решение

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

3

Другие решения

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

Наихудшими последствиями такого подхода, imho, являются:

  • взрыв время компиляции: при каждом редактировании вашего кода вам придется перестраивать все файлы, содержащие этот заголовок; это действительно серьезная проблема, если вы не будете продолжать использовать подход «.h» / «. cpp» во время разработки, а затем переставлять свой код в заголовок только в конце
  • двоичный раздувание кода: все ваши функции должны быть объявлены «встроенными», так что вы можете улучшить производительность, но вы может (1) также иметь репликацию двоичного кода каждый раз, когда вы используете функцию

(1) см Клаус комментарий а также встроенное описание на cppreference.com (цитируется ниже):

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

3