Я всегда использовал файл *.h для своих определений классов, но, прочитав некоторый код библиотеки boost, я понял, что все они используют *.hpp. У меня всегда было отвращение к этому расширению файла, думаю, в основном потому, что я к нему не привык.
Каковы преимущества и недостатки использования *.hpp перед *.h?





Неважно, какое расширение вы используете. Любой из них в порядке.
Я использую *.h для C и *.hpp для C++.
Вы можете называть свои включения как угодно.
Просто нужно указать это полное имя в #include.
Я предлагаю, если вы работаете с C, использовать .h, а когда с C++, использовать .hpp.
В конце концов, это просто условность.
Codegear C++ Builder использует .hpp для файлов заголовков, автоматически генерируемых из исходных файлов Delphi, и файлы .h для ваших «собственных» файлов заголовков.
Итак, когда я пишу файл заголовка C++, я всегда использую .h.
На одной из моих работ в начале 90-х мы использовали .cc и .hh для исходного и заголовочного файлов соответственно. Я по-прежнему предпочитаю его всем альтернативам, вероятно, потому, что его легче всего печатать.
Недавно я начал использовать *.hpp для заголовков C++.
Причина в том, что я использую emacs в качестве основного редактора, и он автоматически переходит в c-режим при загрузке файла *.h и в режим C++ при загрузке файла *.hpp.
Кроме того, я не вижу веских причин для выбора *.h вместо *.hpp или наоборот.
Расширение исходного файла может иметь значение для вашей системы сборки, например, у вас может быть правило в вашем make-файле для файлов .cpp или .c, или ваш компилятор (например, Microsoft cl.exe) может компилировать файл как C или C++ в зависимости от расширение.
Поскольку вы должны предоставить директиве #include полное имя файла, расширение файла заголовка не имеет значения. Вы можете включить файл .c в другой исходный файл, если хотите, потому что это просто текстовое включение. У вашего компилятора может быть возможность сбросить предварительно обработанный вывод, который прояснит это (Microsoft: /P для предварительной обработки в файл, /E для предварительной обработки в stdout, /EP для исключения директив #line, /C для сохранения комментариев)
Вы можете использовать .hpp для файлов, которые имеют отношение только к среде C++, т.е. они используют функции, которые не будут компилироваться в C.
Вот несколько причин, по которым заголовки C и C++ называются по-разному:
Помните, что C - это нет C++, и смешивание и сопоставление может быть очень опасным, если вы не знаете, что делаете. Правильное присвоение названий источникам поможет вам отличить языки друг от друга.
Я предпочитаю .hpp для C++, чтобы дать понять редакторам и другим программистам, что это заголовок C++, а не файл заголовка C.
Я использую .h, потому что это то, что использует Microsoft и что создает их генератор кода. Не нужно идти против течения.
не везде, во многих примерах (например, WINDDK) используется .hpp
Когда речь заходит о C++, я бы не назвал Microsoft «зерном».
@ Бретт, это твоя работа. И даже если это не так, это чертовски популярный компилятор.
@MarkRansom Я больше имел в виду историю использования Microsoft C. IMO VC++ - отличный компилятор.
@developerbmw Я бы сказал, что MSVC - это зерно для программ Windows, а GCC - это зерно для программ * nix, лично. Насколько мне известно, это те самые компиляторы для этих платформ, с которыми стараются оставаться совместимыми.
Я всегда считал, что заголовок .hpp - это своего рода портмоне файлов .h и .cpp ... заголовок, который также содержит детали реализации.
Обычно, когда я видел (и использую) .hpp в качестве расширения, соответствующего файла .cpp не было. Как уже говорили другие, это не жесткое правило, просто то, как я обычно использую файлы .hpp.
C++ («C Plus Plus») имеет смысл как .cpp.
Заголовочные файлы с расширением .hpp не имеют такой логической схемы.
Я использую .hpp, потому что хочу, чтобы пользователь различал, какие заголовки являются заголовками C++, а какие заголовки - заголовками C.
Это может быть важно, когда в вашем проекте используются модули C и C++: как кто-то объяснил до меня, вы должны делать это очень осторожно, и все начинается с «контракта», который вы предлагаете через расширение.
(Или .hxx, или .hh, или что-то еще)
Этот заголовок предназначен только для C++.
Если вы используете модуль C, даже не пытайтесь его включать. Вам это не понравится, потому что не делается никаких усилий, чтобы сделать его дружественным к C (слишком много будет потеряно, например, перегрузка функций, пространства имен и т. д. И т. Д.).
Этот заголовок может быть включен как источником C, так и источником C++, прямо или косвенно.
Его можно включить напрямую, будучи защищенным макросом __cplusplus:
extern "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
Это довольно необычно для многих проектов на C++. Файлы .h используются для очень не-C'ish вещей.
@einpoklum: Конечно. Но я стараюсь избегать поведения «Обезьяна видит, как обезьяна делает». В текущем случае доступны оба расширения (и другие), поэтому я стараюсь, чтобы они действительно учитывались. Наличие этого контракта с кодом, совместно используемым с клиентами, очень полезно: каждый (то есть сотни разработчиков) знает, что файлы ".H" должны использоваться клиентами, использующими компилятор C, поэтому нет никаких сомнений в том, что там можно разместить или нет. И все (включая клиентов) знают, что файлы ".HPP" никогда не будут пытаться быть дружественными к Си. Все выигрывают.
@paercebal, значит, вы предлагаете .ЧАС вместо .час и .HPP вместо .hpp?
@GeofSawaya: Нет, извините. Это привычка. При написании статей я использую расширения в верхнем регистре, чтобы различать файлы по типу, например, «.HPP файлы». Но расширения фактических файлов, которые есть на моем жестком диске, всегда в нижнем регистре, даже в названии нет, например "MyClass.hpp" или "module.hpp"
Спасибо, @paercebal. Я становился педантичным
В книге по C++ "Язык программирования C++, третье издание" Бьярна Страуструпа №1, которую необходимо прочитать, он использует * .h. Поэтому я считаю, что лучше всего использовать * .h.
Однако и * .hpp тоже подойдет!
Если кто-то написал книгу о чем-то, чему он научился от других, которые узнали это из другой (возможно, той же самой) книги, написанной кем-то, у кого, возможно, был доступ к первоисточнику, то это то, что они делают, что угодно, но не цель быть передовой практикой.
Просто упомяну: я на самом деле отдал это. Но я бы поддержал его, если бы там говорилось, что «ISO / IEC N3690» или любой другой проект C++ заменяет «Язык программирования C++, третье издание Бьярна Страуструпа». Хотя это было бы правильным аргументом, поскольку в самом языке вообще нет упоминания .hpp.
@zaibis, вы ведь знаете, что Бьярн Страуструп изобрел C++?
@tumtumtum: я не знал об этом. Но в любом случае, даже в этом случае, это все еще документ комитета, поддерживающий стандарт, который и является справочной информацией. Даже если он изобретатель языка, это уже не его решение. Таким образом, хотя это и делает этот ответ более ценным, его аргументация все еще не обоснована.
РЕДАКТИРОВАТЬ [Добавлено предложение Дэна Ниссенбаума]:
Согласно одному соглашению, файлы .hpp используются, когда прототипы определены в самом заголовке. Такие определения в заголовках полезны в случае шаблонов, поскольку компилятор генерирует код для каждого типа только при создании экземпляра шаблона. Следовательно, если они не определены в файлах заголовков, их определения не будут разрешены во время компоновки из других единиц компиляции. Если ваш проект - это проект только на C++, в котором интенсивно используются шаблоны, это соглашение будет полезно.
Некоторые библиотеки шаблонов, которые придерживаются этого соглашения, предоставляют заголовки с расширениями .hpp, чтобы указать, что у них нет соответствующих файлов .cpp.
другое соглашение - использовать .h для заголовков C и .hpp для C++; хорошим примером может служить библиотека boost.
Quote from Boost FAQ,
File extensions communicate the "type" of the file, both to humans and to computer programs. The '.h' extension is used for C header files, and therefore communicates the wrong thing about C++ header files. Using no extension communicates nothing and forces inspection of file contents to determine type. Using '.hpp' unambiguously identifies it as C++ header file, and works well in actual practice. (Rainer Deyke)
Ничего из этого неверно, когда дело доходит до генерации кода или связывания, не имеет значения, является ли файл .h или .hpp.
разве это не вопрос условности? Библиотека std C++ предоставляет все свои заголовки без какого-либо расширения. использование ".hpp" просто указывает на то, что прототипы определены в одном файле и не будет никакого соответствующего файла .cpp.
Я думаю, что этот ответ полезен, за исключением того, что в нем отсутствует очень простая, но важная фраза: «по соглашению, а не по правилам языка» (где-то).
Инструментам и людям легко отличить что-нибудь. Вот и все.
При обычном использовании (ускорение и т. д.) .hpp - это, в частности, заголовки C++. С другой стороны, .h предназначен только для заголовков, отличных от C++ (в основном C). Как правило, точно определить язык контента сложно, поскольку существует множество нетривиальных случаев, поэтому эта разница часто делает готовый к использованию инструмент простым в написании. Для людей, однажды получивших условность, его также легко запомнить и легко использовать.
Однако я бы отметил, что сама конвенция не всегда работает, как ожидалось.
.hpp - не единственный выбор. Почему не .hh или .hxx? (Хотя в любом случае вам обычно требуется хотя бы одно стандартное правило относительно имен файлов и путей.)Я лично использую как .h, так и .hpp в своих проектах на C++. Я не следую приведенному выше соглашению, потому что:
.h на github.com. (В комментариях может быть что-то вроде Shebang для этих исходных файлов, чтобы быть лучшими метаданными, но это даже не является общепринятым, как имена файлов, поэтому в целом также ненадежно.)Я обычно использую .hpp для заголовков C++, и заголовки должны использоваться (поддерживаться) в стиле только заголовок, например. как библиотеки шаблонов. Для других заголовков в .h либо существует соответствующий файл .cpp в качестве реализации, либо это заголовок, отличный от C++. Последнее легко различить по содержимому заголовка людьми (или инструментами с явными встроенными метаданными, если необходимо).
Я отвечаю на это как напоминание, чтобы указать на мои комментарии к ответу "user1949346" на этот же OP.
Итак, как многие уже ответили: в любом случае можно. Далее следует акцент на собственных впечатлениях.
Вводный, как и в предыдущих упомянутых комментариях, я считаю, что расширения заголовка C++ предлагаются как .h, если на самом деле нет причин против этого.
Поскольку документы ISO / IEC используют эту нотацию файлов заголовков, и в документации по .hpp на их языке даже не встречается строка, соответствующая C++.
Но теперь я стремлюсь к обоснованной причине, ПОЧЕМУ в любом случае это нормально, и особенно почему это не является предметом самого языка.
Итак, поехали.
Документация C++ (на самом деле я ссылаюсь на версию N3690) определяет, что заголовок должен соответствовать следующему синтаксису:
2.9 Header names
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.>, включите, например:
#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 для определений ваших классов» - это:
Оба одинаково верны и применимы до тех пор, пока отсутствуют внешние ограничения.
1From what I know, apparently, it is the boost framework that came up with that .hpp extension.
2Of course I can't say what some future versions will bring with it!
У какого-либо конкретного расширения нет никаких преимуществ, кроме того, что одно может иметь другое значение для вас, компилятора и / или ваших инструментов. header.h - допустимый заголовок. header.hpp - допустимый заголовок. header.hh - допустимый заголовок. header.hx - допустимый заголовок. h.header - допустимый заголовок. this.is.not.a.valid.header - допустимый заголовок для отказа. ihjkflajfajfklaf - допустимый заголовок. Пока имя может быть правильно проанализировано компилятором и файловая система поддерживает его, это действительный заголовок, и единственным преимуществом его расширения является то, что в него читают.
При этом возможность точно делать предположения на основе расширения полезна очень, поэтому было бы разумно использовать легко понятный набор правил для ваших файлов заголовков. Лично я предпочитаю делать что-то вроде этого:
.h. Никакой двусмысленности..h, а заголовок, совместимый с C++, но не C, получает .hpp или .hh или что-то в этом роде.Это, конечно, всего лишь один из способов обработки расширений много, и вы не всегда можете доверять своему первому впечатлению, даже если все кажется простым. Например, я видел упоминание об использовании .h для обычных заголовков и .tpp для заголовков, которые содержат только определения для шаблонных функций-членов класса, с файлами .h, которые определяют шаблонные классы, включая файлы .tpp, которые определяют их функции-члены (вместо .h заголовок, непосредственно содержащий как объявление функции, так и определение). Другой пример: многие люди всегда отражают язык заголовка в его расширении, даже если нет шансов на двусмысленность; для них .h всегда является заголовком C, а .hpp (или .hh, или .hxx и т. д.) всегда является заголовком C++. И опять же, некоторые люди используют .h для «заголовка, связанного с исходным файлом» и .hpp для «заголовка со всеми встроенными функциями».
Учитывая это, основное преимущество будет заключаться в том, чтобы ваши заголовки всегда назывались в одном стиле и делали этот стиль очевидным для любого, кто изучает ваш код. Таким образом, любой, кто знаком с вашим обычным стилем кодирования, сможет определить, что вы имеете в виду под тем или иным расширением, с помощью беглого взгляда.
Бьярн Страуструп и Херб Саттер сформулировали этот вопрос в своих рекомендациях по ядру C++, которые можно найти по адресу: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-source, который также относится к последним изменениям в стандартном расширении (C++ 11, C++ 14 и т. д.)
SF.1: Use a .cpp suffix for code files and .h for interface files if your Y project doesn't already follow another convention Reason
It's a longstanding convention. But consistency is more important, so if your project uses something else, follow that. Note
This convention reflects a common use pattern: Headers are more often shared with C to compile as both C++ and C, which typically uses .h, and it's easier to name all headers .h instead of having different extensions for just those headers that are intended to be shared with C. On the other hand, implementation files are rarely shared with C and so should typically be distinguished from .c files, so it's normally best to name all C++ implementation files something else (such as .cpp).
The specific names .h and .cpp are not required (just recommended as a default) and other names are in widespread use. Examples are .hh, .C, and .cxx. Use such names equivalently. In this document, we refer to .h and .cpp > as a shorthand for header and implementation files, even though the actual extension may be different.
Your IDE (if you use one) may have strong opinions about suffices.
Я не большой поклонник этого соглашения, потому что, если вы используете популярную библиотеку, такую как boost, ваша согласованность уже нарушена, и вам лучше использовать .hpp.
Как многие здесь уже упоминали, я также предпочитаю использовать .hpp для библиотек только для заголовков, которые используют классы / функции шаблонов. Я предпочитаю использовать .h для файлов заголовков, сопровождаемых исходными файлами .cpp, общими или статическими библиотеками.
Большинство разрабатываемых мной библиотек основаны на шаблонах и, следовательно, должны быть только заголовками, но при написании приложений я стараюсь отделять объявление от реализации и в итоге получаю файлы .h и .cpp.
К счастью, это просто.
Вам следует использовать расширение .hpp, если вы работаете с C++, и вы должны использовать .h для C или смешивать C и C++.
Лично я считаю, что подсветка C++ - хорошая идея даже в заголовках C. Я был на обоих концах ситуации, когда кто-то хотел включить ваш заголовок C из C++, но он использует ключевое слово C++ в качестве имени параметра ...