*.h или *.hpp для определения классов
Я всегда использовал файл *.h
для определения моего класса, но, прочитав некоторый код библиотеки boost, я понял, что они все используют *.hpp
. У меня всегда было отвращение к расширению этого файла, я думаю, в основном потому, что я не привык к нему.
В чем преимущества и недостатки использования *.hpp
над *.h
?
Ответы
Ответ 1
Вот несколько причин для различного наименования заголовков C vs С++:
- Автоматическое форматирование кода, у вас могут быть разные рекомендации по форматированию кода на C и С++. Если заголовки разделены расширением, вы можете настроить ваш редактор на автоматическое применение соответствующего форматирования.
- Именование, я был в проектах, где были библиотеки, написанные на C, а затем оболочки были реализованы на С++. Поскольку заголовки обычно имели похожие имена, то есть Feature.h vs Feature.hpp, их было легко отличить друг от друга.
- Включение, возможно, ваш проект имеет более подходящие версии, доступные на С++, но вы используете версию C (см. выше). Если заголовки названы после языка, в котором они реализованы, вы можете легко определить все C-заголовки и проверить версии С++.
Помните, что C - это не С++, и может быть очень опасно смешивать и сопоставлять, если вы не знаете, что делаете. Именование ваших источников соответствующим образом помогает вам отличать языки.
Ответ 2
Я использую.hpp, потому что хочу, чтобы пользователь различал заголовки C++ и заголовки C.
Это может быть важно, когда ваш проект использует модули C и C++: как кто-то еще объяснил до меня, вы должны делать это очень осторожно, и все начинается с "контракта", который вы предлагаете через расширение
.hpp: C++ Заголовки
(Или.hxx, или.hh, или как там)
Этот заголовок только для C++.
Если вы находитесь в модуле C, даже не пытайтесь включить его. Вам это не понравится, потому что не делается никаких усилий, чтобы сделать его C-дружественным (слишком много будет потеряно, например, перегрузка функций, пространства имен и т.д. И т.д.).
.h: C/C++ совместимые или чистые заголовки C
Этот заголовок может быть включен как источником C, так и источником C++, прямо или косвенно.
Он может быть включен напрямую, будучи защищенным __cplusplus
:
- Это означает, что с точки зрения C++ C-совместимый код будет определен как
extern "C"
. - С точки зрения C весь код C будет отчетливо виден, но код C++ будет скрыт (потому что он не будет компилироваться в компиляторе C).
Например:
#ifndef MY_HEADER_H
#define MY_HEADER_H
#ifdef __cplusplus
extern "C"
{
#endif
void myCFunction() ;
#ifdef __cplusplus
} // extern "C"
#endif
#endif // MY_HEADER_H
Или же он может быть косвенно включен в соответствующий заголовок.hpp, содержащий его с объявлением extern "C"
.
Например:
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
extern "C"
{
#include "my_header.h"
}
#endif // MY_HEADER_HPP
а также:
#ifndef MY_HEADER_H
#define MY_HEADER_H
void myCFunction() ;
#endif // MY_HEADER_H
Ответ 3
Я всегда рассматривал заголовок .hpp
как своего рода portmanteau файлов .h
и .cpp
... заголовок, который также содержит сведения о реализации.
Обычно, когда я видел (и использовал) .hpp
в качестве расширения, нет соответствующего файла .cpp
. Как говорили другие, это не сложное и быстрое правило, просто как я обычно использую файлы .hpp
.
Ответ 4
Не важно, какое расширение вы используете. Любой из них в порядке.
Я использую *.h
для C и *.hpp
для С++.
Ответ 5
EDIT [Добавлено предложение от Дэна Ниссенбаума]:
По одному соглашению файлы .hpp используются, когда прототипы определены в самом заголовке. Такие определения в заголовках полезны в случае шаблонов, поскольку компилятор генерирует код для каждого типа только при создании экземпляра. Следовательно, если они не определены в заголовочных файлах, их определения не будут разрешены во время соединения с другими единицами компиляции. Если ваш проект - это только проект на C++, который сильно использует шаблоны, это соглашение может быть полезно.
Некоторые библиотеки шаблонов, которые придерживаются этого соглашения, предоставляют заголовки с расширением .hpp, чтобы указать, что у них нет соответствующих файлов .cpp.
В некоторых других библиотеках шаблонов используется другое соглашение, например, использование .h для заголовков C и .hpp для С++; хорошим примером может служить библиотека ускорения.
Цитата из FAQ Boost,
Расширения файлов сообщают "тип" файла, как для людей и к компьютерным программам. Расширение '.h' используется для заголовка C файлы и, следовательно, сообщает о неправильном заголовке С++ файлы. Использование без расширения ничего не сообщает и проводит проверку содержимого файла для определения типа. Использование ".hpp" недвусмысленно идентифицирует его как заголовочный файл С++ и хорошо работает на практике. (Райнер Дейк)
Ответ 6
Недавно я начал использовать *.hpp
для заголовков С++.
Причина в том, что я использую emacs в качестве основного редактора и автоматически переходит в c-режим при загрузке файла *.h
и в режиме С++ при загрузке файла *.hpp
.
Помимо этого факта я не вижу веских оснований для выбора *.h
над *.hpp
или наоборот.
Ответ 7
Вы можете позвонить, что включает в себя все, что вам нравится.
Просто нужно указать это полное имя в #include
.
Я предлагаю, если вы работаете с C, чтобы использовать .h
, а когда с С++ использовать .hpp
.
Это, в конце концов, просто соглашение.
Ответ 8
Я предпочитаю .hpp для С++, чтобы дать понять как редакторам, так и другим программистам, что это заголовок С++, а не заголовочный файл C.
Ответ 9
В одном из моих заданий в начале 90-х мы использовали .cc и .hh для исходных и заголовочных файлов соответственно. Я по-прежнему предпочитаю его по всем альтернативам, возможно, потому что это проще всего напечатать.
Ответ 10
С++ ( "C Plus Plus" ) имеет смысл как .cpp
Наличие файлов заголовков с расширением .hpp не имеет одинакового логического потока.
Ответ 11
Я отвечаю на это как напоминание, чтобы указать на мой комментарий (я) к "user1949346" ответ на этот же ОП.
Так что многие уже ответили: в любом случае это хорошо. Далее следует акцент на собственных впечатлениях.
Вводный, как и в предыдущих названных комментариях, мое мнение C++
расширения заголовка C++
предлагаются как .h
если на самом деле нет причин против этого.
Поскольку документы ИСО/МЭК использовать эти обозначения файлов заголовков и не совпадающей строки в .hpp
происходит даже на их языке документаций о C++
.
Но теперь я стремлюсь по приемлемой причине, ПОЧЕМУ любой путь в порядке, и особенно почему это не предмет языка, который он сам.
Итак, поехали.
Документация C++
(на самом деле я ссылаюсь на версию N3690) определяет, что заголовок должен соответствовать следующему синтаксису:
2.9 Имена заголовков
header-name:
< h-char-sequence >
" q-char-sequence "
h-char-sequence:
h-char
h-char-sequence h-char
h-char:
any member of the source character set except new-line and >
q-char-sequence:
q-char
q-char-sequence q-char
q-char:
any member of the source character set except new-line and "
Таким образом, как мы можем извлечь из этой части, имя файла заголовка также может быть любым, допустимым в исходном коде. За исключением того, что содержит символы '\n'
и в зависимости от того, должен ли он быть включен в <>
он не может содержать >
. Или другой способ, если он включен ""
-include, ему не разрешено содержать "
.
Другими словами: если у вас была среда, поддерживающая имена файлов, такие как prettyStupidIdea.>
, prettyStupidIdea.>
вроде:
#include "prettyStupidIdea.>"
будет действительным, но:
#include <prettyStupidIdea.>>
будет недействительным. И наоборот.
И даже
#include <<.<>
будет допустимым включаемым именем файла заголовка.
Даже это будет соответствовать C++
, это была бы довольно глупая идея, правда.
И вот почему .hpp
подходит.
Но это не результат комитетов, разрабатывающих решения для языка!
Поэтому обсуждение использования .hpp
аналогично обсуждению .cc
, .mm
или всего, что я читал в других постах на эту тему.
Я должен признать, что я понятия не имею, где .hpp
пришел от 1, но я бы поставил изобретатель некоторого синтаксического анализа инструмента, IDE или что - то другое, связанный с C++
пришел к этой идее, чтобы оптимизировать некоторые внутренние процессы или просто придумать какую - то ( наверное даже для них обязательно) новые соглашения об именах.
Но это не часть языка.
И всякий раз, когда кто-то решает использовать это таким образом. Может быть потому, что ему нравится не больше всего или потому, что некоторые приложения процесса требуют, он никогда 2 является требованием языка. Поэтому тот, кто говорит "pp - это потому, что он используется с C++", просто ошибается в отношении определения языков.
C++ позволяет все, что касается предыдущего абзаца. И если есть что-то, что комитет предложил использовать, то он использует .h
поскольку это расширение используется во всех примерах документа ISO.
Заключение:
Пока вы не видите/не чувствуете необходимости использовать .h
.hpp
или наоборот, вам не стоит беспокоиться. Потому что оба будут формировать правильное имя заголовка одинакового качества по отношению к стандарту. И поэтому все, что ТРЕБУЕТ вам использовать .h
или .hpp
является дополнительным ограничением стандарта, которое может даже противоречить другим дополнительным ограничениям, не совместимым друг с другом. Но поскольку OP не упоминает никаких дополнительных языковых ограничений, это единственный правильный и приемлемый ответ на вопрос
"*.h или *.hpp для ваших определений классов":
Оба являются одинаково правильными и применимыми до тех пор, пока нет внешних ограничений.
1Из того, что я знаю, по-видимому, это фреймворк .hpp
который .hpp
расширение .hpp
.
2Конечно, я не могу сказать, что принесут с собой некоторые будущие версии!
Ответ 12
Codegear С++ Builder использует .hpp для файлов заголовков, автоматически генерируемых из исходных файлов Delphi, и .h файлов для ваших собственных файлов заголовков.
Итак, когда я пишу заголовочный файл С++, я всегда использую .h.
Ответ 13
Bjarne Stroustrup и Herb Sutter имеют отношение к этому вопросу в своих основных принципах С++, описанных в: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-source, который также ссылается на последние изменения в стандартном расширении (С++ 11, С++ 14 и т.д.)
SF.1: используйте суффикс .cpp для файлов кода и .h для файлов интерфейса, если ваш Проект Y еще не соответствует другому соглашению Причина
Это давняя конвенция. Но последовательность важнее, поэтому, если ваш проект использует что-то еще, следуйте этому. Примечание
Это соглашение отражает общую схему использования: заголовки чаще всего разделяются с C для компиляции как С++ и C, который обычно использует .h, и он проще назвать все заголовки .h вместо разных расширений для только те заголовки, которые предназначены для совместного использования с C. С другой стороны, файлы реализации редко используются совместно с C, и поэтому обычно должны быть отличается от .c файлов, поэтому обычно лучше всего назвать все С++ реализация файлов что-то еще (например,.cpp).
Конкретные имена .h и .cpp не требуются (рекомендуется только в качестве по умолчанию), а другие имена широко используются. Примерами являются .hh,.C и .cxx. Используйте такие имена эквивалентно. В этом документе мы ссылаемся на .h и .cpp > как стенографию для файлов заголовков и реализации, хотя фактическое расширение может быть другим.
Ваша IDE (если вы ее используете) может иметь сильные мнения о достаточности.
Я не большой поклонник этого соглашения, потому что, если вы используете популярную библиотеку, например boost, ваша последовательность уже нарушена, и вам лучше использовать .hpp.
Ответ 14
Как уже упоминалось выше, я также предпочитаю использовать .hpp для библиотек только для заголовков, которые используют шаблонные классы/функции. Я предпочитаю использовать .h для файлов заголовков, сопровождаемых исходными файлами .cpp или общими или статическими библиотеками.
Большинство разрабатываемых библиотек основаны на шаблонах и поэтому должны быть только заголовками, но при написании приложений я склонен отделять декларацию от реализации и в конечном итоге с файлами .h и .cpp
Ответ 15
К счастью, это просто.
Вы должны использовать расширение .hpp, если вы работаете с С++, и вы должны использовать .h для C или для смешивания C и С++.
Ответ 16
Я использую .h, потому что это то, что использует Microsoft, и то, что создает генератор кода. Не нужно идти против зерна.
Ответ 17
Инструментам и людям легко отличить что-то. Что это.
В обычном использовании (с помощью boost и т.д.) .hpp
- это, в частности, заголовки С++. С другой стороны, .h
для не-С++ - только заголовки (в основном C). Точно определить язык содержимого, как правило, сложно, так как существует много нетривиальных случаев, поэтому это различие часто делает готовый к использованию инструмент легким для записи. Для людей, после получения конвенции, он также легко запоминается и прост в использовании.
Однако я бы отметил, что сама конвенция не всегда работает, как и ожидалось.
- Он не принуждается спецификацией языков, ни C, ни С++. Существует много проектов, которые не соответствуют конвенции. Как только вам нужно объединить (смешать) их, это может быть неприятно.
-
.hpp
сам по себе не единственный выбор. Почему бы не .hh
или .hxx
? (Хотя в любом случае вам обычно требуется хотя бы одно обычное правило о именах файлов и путях.)
Я лично использую как .h
, так и .hpp
в моих проектах на С++. Я не следую вышеприведенному соглашению, потому что:
- Языки, используемые каждой частью проектов, явно документированы. Нет возможности смешать C и С++ в том же модуле (каталог). Каждая библиотека 3rdparty должна соответствовать этому правилу.
- Также документируются соответствующие спецификации языка и разрешенные языковые диалекты, используемые проектами. (Фактически, я даже документирую источник стандартных функций и исправления ошибок (по стандартному языку)). Это несколько более важно чем различать используемые языки, поскольку он слишком подвержен ошибкам, а стоимость теста (например, совместимость с компиляторами) может быть значительным (сложным и трудоемким), особенно в проекте, который уже находится в почти чистом С++. Имена файлов слишком слабы, чтобы справиться с этим.
- Даже для одного и того же диалекта С++ могут быть более важные свойства, подходящие для разницы. Например, см. Соглашение ниже.
- Имена файлов - это, по сути, фрагменты хрупких метаданных. Нарушение конвенции не так легко обнаружить. Чтобы быть стабильным в отношении контента, инструмент должен в конечном итоге не только зависеть от имен. Разница между расширениями - это всего лишь намек. Не следует ожидать, что инструменты, использующие его, будут вести себя одинаково все время, например. обнаружение языка
.h
файлов на github.com. (Возможно, что-то в комментариях, таких как shebang, чтобы эти исходные файлы были лучшими метаданными, но он даже не является обычным, как имена файлов, поэтому также не надежны в целом.)
Обычно я использую .hpp
в заголовках С++, и заголовки должны использоваться (поддерживаться) только в виде заголовка, например. как библиотеки шаблонов. Для других заголовков в .h
либо имеется соответствующий файл .cpp
как реализация, либо это не-С++-заголовок. Последнее тривиально дифференцировать через содержимое заголовка людьми (или инструментами с явными встроенными метаданными, если это необходимо).
Ответ 18
Расширение исходного файла может иметь смысл для вашей системы сборки, например, у вас может быть правило в файле makefile для файлов .cpp
или .c
, или ваш компилятор (например, Microsoft cl.exe
) может скомпилировать файл как C или С++ в зависимости от расширения.
Поскольку вы должны предоставить полное имя файла директиве #include
, расширение файла заголовка не имеет значения. Вы можете включить файл .c
в другой исходный файл, если хотите, потому что он включает только текстовый текст. У вашего компилятора может быть возможность сбрасывать предварительно обработанный вывод, который сделает это ясно (Microsoft: /P
для предварительной обработки файла, /E
для предварительной обработки stdout
, /EP
, чтобы опустить директивы #line
, /C
сохранить комментарии)
Вы можете использовать .hpp
для файлов, которые имеют отношение только к среде С++, то есть они используют функции, которые не будут компилироваться в C.
Ответ 19
В "языке программирования С++, третьем выпуске Bjarne Stroustrup", читаемой С++ книге nº1, он использует *.h. Поэтому я предполагаю, что наилучшей практикой является использование *.h.
Однако, *.hpp тоже отлично!
Ответ 20
Нет никакого преимущества для какого-либо конкретного расширения, кроме того, что у вас может быть другое значение для вас, компилятора и/или ваших инструментов. header.h
- допустимый заголовок. header.hpp
является допустимым заголовком. header.hh
является допустимым заголовком. header.hx
является допустимым заголовком. h.header
является допустимым заголовком. this.is.not.a.valid.header
является допустимым заголовком в отрицании. ihjkflajfajfklaf
является допустимым заголовком. Пока имя может быть правильно проанализировано компилятором, а файловая система поддерживает его, он является допустимым заголовком, и единственным преимуществом его расширения является то, что он читает в нем.
Если говорить, что возможность точно делать предположения на основе расширения очень полезна, поэтому было бы разумно использовать легко понятный набор правил для ваших файлов заголовков. Лично я предпочитаю делать что-то вроде этого:
- Если есть уже установленные правила, следуйте им, чтобы предотвратить путаницу.
- Если все исходные файлы в проекте предназначены для одного языка, используйте
.h
. Там нет двусмысленности.
- Если некоторые заголовки совместимы с несколькими языками, а другие совместимы только с одним языком, расширения основаны на самом ограничительном языке, совместимом с заголовком. Заголовок, совместимый с C или с C и С++, получает
.h
, а заголовок, совместимый с С++, но не C, получает .hpp
или .hh
или что-то вроде этого.
Это, конечно, является одним из многих способов обработки расширений, и вы не можете доверять своему первому впечатлению, даже если все кажется простым. Например, я видел упоминание использования .h
для обычных заголовков и .tpp
для заголовков, содержащих только определения для шаблонных функций-членов класса, с .h
файлами, которые определяют шаблонные классы, включая файлы .tpp
, которые определяют их функции-члены (вместо заголовка .h
, содержащего как объявление функции, так и определение). В другом примере многие люди всегда отражают язык заголовка в своем расширении, даже если нет возможности двусмысленности; для них .h
всегда является заголовком C, а .hpp
(или .hh
, или .hxx
и т.д.) всегда является заголовком С++. И все же, некоторые люди используют .h
для "заголовка, связанного с исходным файлом" и .hpp
для "заголовка со всеми функциями, определенными в строке".
Учитывая это, основное преимущество будет заключаться в том, чтобы последовательно называть ваши заголовки в одном стиле и сделать этот стиль понятным для всех, кто изучает ваш код. Таким образом, любой, кто знаком с вашим обычным стилем кодирования, сможет определить, что вы имеете в виду с любым заданным расширением, просто беглым взглядом.