Для чего используются заголовки файлов

Заголовочный файл

Заголовочный файл (иногда головной файл, англ. header file ), или подключаемый файл — в языках программирования файл, механически «вставляемый» компилятором в исходный текст в том месте, где располагается некоторая директива ( <$I file.inc>в Паскале, #include в Си).

По сложившейся традиции, в заголовочных файлах объявляют функции стандартной библиотеки Си и Си++.

В других языках (например, в Паскале) применяется развитая система модулей. Но и в них заголовочные файлы имеют определённую ценность. Дело в том, что два файла (основной и заголовочный) сливаются в одну единицу трансляции, и поэтому заголовочный файл может содержать директивы препроцессора, незаконченные синтаксические конструкции.

Содержание

Назначение

Чтобы на неё можно было ссылаться из других единиц компиляции, требуется объявить её при помощи прототипа функции, то есть:

Тем не менее, такое объявление требует, чтобы программист обеспечил объявление функции для add в двух местах — в файле, содержащем её выполнение, и в файле, в котором она используется. В случае изменения определения функции программист должен не забыть обновить все прототипы, использованные в программе.

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

Обычно заголовочные файлы применяются только для более чёткого определения интерфейса и обычно содержат комментарии, поясняющие способы использования компонентов, объявленных в файле. В приведённом примере использованные подпрограммы выделены в отдельные исходные файлы, которые должны компилироваться отдельно (исключением в языках Си и C++ являются встраиваемые функции, которые зачастую включаются в заголовочный файл из-за того, что в большинстве случаев использования не получается правильно раскрыть встраиваемую функцию без обращений к их определению во время компиляции).

Сравнение с прямым получением заголовков из откомпилированного модуля

Альтернатива заголовочным файлам — получение информации об объявленных типах, функциях и т. д. напрямую из откомпилированного модуля. Так поступают языки Паскаль, Java и другие.

Преимущества

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

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

Недостатки

В некоторых языках (например, Java) вообще не требуется изменять код одновременно в двух местах.

См. также

Ссылки

Литература

Полезное

Смотреть что такое «Заголовочный файл» в других словарях:

Файл заголовков — Заголовочный файл (иногда головной файл, англ. header file) (или подключаемый файл) в языках программирования Си и C++ файл, содержащий определения типов данных, структуры, прототипы функций, перечисления, макросы препроцессора. Имеет по… … Википедия

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

Файл — У этого термина существуют и другие значения, см. Файл (значения). Файл (англ. file) блок информации на внешнем запоминающем устройстве компьютера, имеющий определённое логическое представление (начиная от простой последовательности… … Википедия

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

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

Препроцессор Си — Препроцессор С/С++ программный инструмент, изменяющий код программы для последующей компиляции и сборки, используемый в языках программирования Си и его потомка C++. Этот препроцессор обеспечивает использование стандартного набора… … Википедия

stdint.h — Стандартная библиотека языка программирования С assert.h complex.h ctype.h errno.h fenv.h float.h inttypes.h iso646.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stdbool.h stddef.h stdint … Википедия

errno.h — Стандартная библиотека языка программирования С assert.h complex.h ctype.h errno.h fenv.h float.h inttypes.h iso646.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stdbool.h stddef.h … Википедия

Iso646.h — Стандартная библиотека языка программирования С assert.h complex.h ctype.h errno.h fenv.h float.h inttypes.h iso646.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stdbool.h stddef.h stdint.h stdio.h … Википедия

Источник

Руководство Google по стилю в C++. Часть 2

Часть 1. Вступление
Часть 2. Заголовочные файлы
Часть 3. Область видимости

Для чего используются заголовки файлов. Смотреть фото Для чего используются заголовки файлов. Смотреть картинку Для чего используются заголовки файлов. Картинка про Для чего используются заголовки файлов. Фото Для чего используются заголовки файлов

Все мы при написании кода пользуемся правилами оформления кода. Иногда изобретаются свои правила, в других случаях используются готовые стайлгайды. Хотя все C++ программисты читают на английском легче, чем на родном, приятнее иметь руководство на последнем.
Эта статья является переводом части руководства Google по стилю в C++ на русский язык.
Исходная статья (fork на github), обновляемый перевод.

Заголовочные файлы

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

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

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

Независимые заголовочные файлы

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

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

Предпочтительно размещать определения для шаблонов и inline-функций в одном файле с их декларациями. И эти определения должны быть включены (include) в каждый .cc файл, использующий их, иначе могут быть ошибки линковки на некоторых конфигурациях сборки. Если же декларации и определения находятся в разных файлах, включение одного должно подключать другой. Не выделяйте определения в отдельные заголовочные файлы (-inl.h). Раньше такая практика была очень популярна, сейчас это нежелательно.

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

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

Блокировка от повторного включения

Для гарантии уникальности, используйте компоненты полного пути к файлу в дереве проекта. Например, файл foo/src/bar/baz.h в проекте foo может иметь следующую блокировку:

Предварительное объявление

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

Определение
«Предварительное объявление» — декларация класса, функции, шаблона без соответствующего определения.

Встраиваемые (inline) функции

Определяйте функции как встраиваемые только когда они маленькие, например не более 10 строк.

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

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

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

Хорошим правилом будет не делать функции встраиваемыми, если они превышают 10 строк кода. Избегайте делать встраиваемыми деструкторы, т.к. они неявно могут содержать много дополнительного кода: вызовы деструкторов переменных и базовых классов!

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

Важно понимать, что встраиваемая функция не обязательно будет скомпилирована в код именно так. Например, обычно виртуальные и рекурсивные функции компилируются со стандартным вызовом. Вообще, рекурсивные функции не должны объявляться встраиваемыми. Основная же причина делать встраиваемые виртуальные функции — разместить определение (код) в самом определении класса (для документирования поведения или удобства чтения) — часто используется для get/set функций.

Имена и Порядок включения (include)

Вставляйте заголовочные файлы в следующем порядке: парный файл (например, foo.h — foo.cc), системные файлы C, стандартная библиотека C++, другие библиотеки, файлы вашего проекта.

Все заголовочные файлы проекта должны указываться относительно директории исходных файлов проекта без использования таких UNIX псевдонимов как . (текущая директория) или .. (родительская директория). Например, google-awesome-project/src/base/logging.h должен включаться так:

Другой пример: если основная функция файлов dir/foo.cc иdir/foo_test.cc это реализация и тестирование кода, объявленного в dir2/foo2.h, то записывайте заголовочные файлы в следующем порядке:

Такой порядок файлов позволяет выявить ошибки, когда в парном заголовочном файле (dir2/foo2.h) пропущены необходимые заголовочные файлы (системные и др.) и сборка соответствующих файлов dir/foo.cc или dir/foo_test.cc завершится ошибкой. Как результат, ошибка сразу же появится у разработчика, работающего с этими файлами (а не у другой команды, которая только использует внешнюю библиотеку).

Обычно парные файлы dir/foo.cc и dir2/foo2.h находятся в одной директории (например, base/basictypes_test.cc и base/basictypes.h), хотя это не обязательно.

Учтите, что заголовочные файлы C, такие как stddef.h обычно взаимозаменяемы соответствующими файлами C++ (cstddef). Можно использовать любой вариант, но лучше следовать стилю существующего кода.

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

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

Например, список заголовочных файлов в google-awesome-project/src/foo/internal/fooserver.cc может выглядеть так:

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

Источник

12.11 – Файлы исходного кода и заголовочные файлы классов

Определение функций-членов вне определения класса

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

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

К счастью, C++ предоставляет способ отделить часть «объявления» класса от его «реализации». Это делается путем определения функций-членов класса вне определения класса. Для этого просто определите функции-члены класса, как если бы они были обычными функциями, но добавив к функциям префикс из имени класса с помощью оператора разрешения области видимости ( :: ) (так же, как для пространства имен).

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

Вот еще один пример, который включает внешний конструктор со списком инициализации членов.

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

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

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

Типы (которые включают в себя классы) не подпадают под действие правила одного определения, которое гласит, что у вас может быть только одно определение в программе. Следовательно, нет проблем с включением через #include определений классов в несколько файлов исходного кода (если бы они были, от классов было бы мало пользы).

Не нарушает ли определение функций-членов в заголовке правило одного определения?

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

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

Поэтому мы рекомендуем следующее:

Параметры по умолчанию

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

Библиотеки

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

Источник

C++/Header file

Содержание

Преамбула

В ЯП C/C++ заголовочные файлы — основной способ подключить к программе типы данных, структуры, прототипы функций, перечислимые типы и макросы, используемые в др. модуле.

Расширения заголовочный файлов

По-умолч. используется расширение «.h»; иногда для заголовочных файлов языка C++ используют расширение «.hpp». Позже было принято, что заголовочные файлы всех стандартных библиотек языка C++ пишутся без расширений. Ранее им давались самые различные расширения: «.h», «.h++», «.hpp», «.hxx», «.hh». Неродным (пользовательским, сторонним) заголовочным файлам принято по-прежнему давать расширение «.h».

Общие сведения

Заголовочный файл в общем случае может содержать любые конструкции языка программирования, но на практике исполняемый код (за исключением inline-функций в C++) в заголовочные файлы не помещают. Например, идентификаторы, которые должны быть объявлены более чем в одном файле, удобно описать в заголовочном файле, а затем его подключать по мере надобности. Подобным же образом работает модульность и в большинстве ассемблеров.

По сложившейся традиции, в заголовочных файлах объявляют функции стандартной библиотеки Си и Си++.

В других ЯП (напр., в Pascal) применяется развитая система модулей. Но и в них заголовочные файлы имеют определённую ценность. Дело в том, что два файла (основной и заголовочный) сливаются в одну единицу трансляции, и поэтому заголовочный файл может содержать директивы препроцессора, незаконченные синтаксические конструкции.

Назначение

Чтобы на неё можно было ссылаться из других единиц компиляции, требуется объявить её при помощи прототипа функции, то есть:

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

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

Обычно заголовочные файлы применяются только для более чёткого определения интерфейса и обычно содержат комментарии, поясняющие способы использования компонентов, объявленных в файле. В приведённом примере использованные подпрограммы выделены в отдельные исходные файлы, которые должны компилироваться отдельно (исключением в языках Си и C++ являются встраиваемые функции, которые зачастую включаются в заголовочный файл из-за того, что в большинстве случаев использования не получается правильно раскрыть встраиваемую функцию без обращений к их определению во время компиляции).

Сравнение с прямым получением заголовков из откомпилированного модуля

Альтернатива заголовочным файлам — получение информации об объявленных типах, функциях и т. д. напрямую из откомпилированного модуля. Так поступают языки Паскаль, Java и другие.

Преимущества

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

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

Упрощается взаимодействие между модулями, написанными на разных языках. Компилятору и компоновщику вообще безразлично, написан вызываемый модуль на том же языке или на другом. К тому же разные языки могут скомпилировать свои модули в одинаковые объектные файлы — в таком случае получается один компоновщик на несколько языков. Точно так же просто сделать библиотеку, которая по выбору пользователя включается в проект в виде CPP-файлов, хранится заранее откомпилированной и прикомпоновывается статически, или прикомпоновывается как DLL.

Недостатки

Проектам из языков семейства Си свойственны сложные схемы сборки проекта. Ведь (как минимум в стандартном C++) надо включить в проект библиотеку — либо в виде CPP-файлов, либо в откомпилированном виде. Даже если (например, в Visual C++) для этого есть директивы препроцессора, библиотеку всё равно придётся собрать.

Источник

2.10 – Заголовочные файлы

Заголовки и их назначение

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

Ключевой момент

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

Использование заголовочных файлов стандартной библиотеки

Рассмотрим следующую программу:

Ключевой момент

Когда дело доходит до функций и переменных, стоит помнить, что заголовочные файлы обычно содержат только объявления функций и переменных, а не их определения (в противном случае может произойти нарушение правила одного определения). std::cout объявлен в заголовке iostream, но определен как часть стандартной библиотеки C++, которая автоматически подключается к вашей программе на этапе линкера.

Для чего используются заголовки файлов. Смотреть фото Для чего используются заголовки файлов. Смотреть картинку Для чего используются заголовки файлов. Картинка про Для чего используются заголовки файлов. Фото Для чего используются заголовки файлов Рисунок 1 – Диаграмма процесса сборки

Лучшая практика

Заголовочные файлы обычно не должны содержать определений функций и переменных, чтобы не нарушать правило одного определения. Исключение сделано для символьных констант (которые мы рассмотрим в уроке «4.14 – const, constexpr и символьные константы»).

Написание собственных заголовочных файлов

(Если вы воссоздаете этот пример с нуля, не забудьте добавить add.cpp в свой проект, чтобы он компилировался).

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

Добавление заголовочного файла в проект работает аналогично добавлению исходного файла (рассматривается в уроке «2.7 – Программы с несколькими файлами исходного кода»). Если вы используете IDE, выполните такие же действия и при появлении запроса выберите Файл заголовка (или C/C++ header) вместо Файла С++ (или C/C++ source). Если вы используете командную строку, просто создайте новый файл в своем любимом редакторе.

Лучшая практика

Лучшая практика

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

Вот наш завершенный заголовочный файл:

Следовательно, наша программа будет правильно компилироваться и компоноваться.

Для чего используются заголовки файлов. Смотреть фото Для чего используются заголовки файлов. Смотреть картинку Для чего используются заголовки файлов. Картинка про Для чего используются заголовки файлов. Фото Для чего используются заголовки файлов Рисунок 2 – Диаграмма процесса сборки

Включение заголовочного файла в соответствующий исходный файл

Позже вы увидите, что большинство исходных файлов включают свой соответствующий заголовочный файл, даже если он им не нужен. Зачем?

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

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

При разработке библиотеки включение заголовочного файла в исходный файл может даже помочь в раннем обнаружении ошибок.

Лучшая практика

При написании исходного файла включите в него соответствующий заголовочный файл (если он существует), даже если он вам пока не нужен.

Поиск и устранение проблем

Угловые скобки и двойные кавычки

Когда мы используем угловые скобки, мы сообщаем препроцессору, что это заголовочный файл, который мы не писали сами. Компилятор будет искать заголовок только в каталогах, указанных в каталогах включаемых файлов (include directories). Каталоги включаемых файлов настраиваются как часть вашего проекта / настроек IDE / настроек компилятора и обычно по умолчанию используются для каталогов, содержащих заголовочные файлы, которые поставляются с вашим компилятором и/или ОС. Компилятор не будет искать заголовочный файл в каталоге исходного кода вашего проекта.

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

Правило

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

Лучшая практика

Включение заголовочных файлов из других каталогов

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

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

Лучший способ – сообщить вашему компилятору или IDE, что у вас есть куча заголовочных файлов в каком-то другом месте, чтобы он смотрел туда, когда не может найти их в текущем каталоге. Обычно это можно сделать, установив путь включения (include path) или каталог поиска (search directory) в настройках проекта в IDE.

Для пользователей Visual Studio

Кликните правой кнопкой мыши на своем проекте в обозревателе решений и выберите Свойства (Properties), затем вкладку Каталоги VC++.(VC++ Directories). Здесь вы увидите строку с названием «Включаемые каталоги» (Include Directories). Добавьте каталоги, в которых компилятор должен искать дополнительные заголовочные файлы.

Для пользователей Code::Blocks

В Code:: Blocks перейдите в меню Project (Проект) и выберите Build Options (Параметры сборки), затем вкладку Search directories (Каталоги поиска). Добавьте каталоги, в которых компилятор должен искать дополнительные заголовочные файлы.

Для пользователей GCC/G++

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

Заголовочные файлы могут включать другие заголовочные файлы

Обычно для заголовочных файлов требуется объявление или определение, которое находится в другом заголовочном файле. Из-за этого заголовочные файлы часто включают с помощью #include другие заголовочные файлы.

Когда ваш исходный файл включает с помощью #include первый заголовочный файл, вы также получите любые другие заголовочные файлы, которые были включены в первый заголовочный файл (и любые заголовочные файлы, которые были включены в предыдущие, и т.д.). Эти дополнительные заголовочные файлы иногда называют «транзитивными включениями», поскольку они включаются неявно.

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

Лучшая практика

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

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

Порядок #include заголовочных файлов

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

Лучшая практика

Упорядочьте свои включения с #include следующим образом: сначала ваши собственные пользовательские заголовки, затем заголовки сторонних библиотек, затем заголовки стандартных библиотек; заголовки в каждом разделе должны быть отсортированы в алфавитном порядке.

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

Рекомендации по использованию заголовочных файлов

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *