2015-06-11 9 views
2

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

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

Но это все?

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

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

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

ответ

3

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

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

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

(1) см Klauscomment и inline description at cppreference.com (цит ниже):

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

+1

Я абсолютно не согласен с кодом раздувания! Мой опыт заключается в том, что инкрустация идет вперед с постоянными расчетами и распространением, что в основном приводит к «оптимизированным прочим» параметрам и функциям. С C++ 11 и constexpr этот эффект намного выше, чем удвоение исполняемого кода в строках. – Klaus

+0

@Klaus Действительно интересно! Я думаю, что, в зависимости от нескольких факторов, таких как «длина» функции и других, можно иметь разные типы поведения. Как вы думаете? –

+1

Можете ли вы подробнее рассказать о встроенных? Я всегда немного смущен о «inline = функции, определенной в заголовке» и «inline = function с ключевым словом inline» (что верно только в том случае, если функция определена в заголовке, верно?) – user463035818

3

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