Должен ли каждый файл C или C ++ иметь связанный заголовочный файл?

git show somebranch:path/to/your/file

вы также можете сделать несколько файлов и объединить их:

git show branchA~10:fileA branchB^^:fileB

Вы должны предоставить полный путь к файлу.

Если вы хотите получить файл в локальном каталоге (верните только один файл), вы можете проверить:

git checkout somebranch^^^ -- path/to/file
13
задан Matt Fenwick 14 March 2012 в 02:42
поделиться

14 ответов

Необычно иметь main.h, так как обычно нет ничего, что должно быть подвергнуто другим единицам компиляции во время компиляции. main() самостоятельно потребности, которые будут представлены для linker/start-up-code, но они не используют заголовочные файлы.

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

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

не имеет смысла в этом случае иметь отдельные заголовочные файлы для каждого файла C, поскольку заголовок является API, представлением библиотеки пользователю. Я сомневаюсь, что пользователь хотел бы включать 6 заголовочных файлов только, чтобы быть в состоянии использовать функции. Был бы один btree.h файл и сингл btree.lib файл, содержащий все объекты B-дерева, созданные из файлов индивидуума C.

Другой пример может быть найден в стандарте C заголовки. Мы не знаем наверняка, существует ли несколько файлов C для stdio.h функции (это - то, как я сделал бы это, но это не единственный путь), но, даже если было, их рассматривают как единицу с точки зрения API. Вы не должны включать stdio_printf.h, stdio_fgets.h и так далее - существует сингл stdio.h для стандартной части ввода-вывода библиотеки времени выполнения C.

30
ответ дан paxdiablo 14 March 2012 в 13:42
поделиться

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

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

0
ответ дан SingleNegationElimination 14 March 2012 в 13:42
поделиться

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

первое такой случай main.c/cpp файлы. Этот класс не предназначен, чтобы быть включенным и как таковой нет никакой потребности в заголовочном файле.

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

0
ответ дан David Rodríguez - dribeas 14 March 2012 в 13:42
поделиться

Как уже отмечено, обычно, будет один заголовок (.h) файл для каждого источника (.c или .cpp) файл.

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

(Также отмеченный Миром): для основной программы не обычно нужен ее собственный заголовок - никакой другой исходный код не должен использовать услуги, которые это предоставляет; это использует услуги, предоставленные другими файлами.

0
ответ дан Jonathan Leffler 14 March 2012 в 13:42
поделиться

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

1
ответ дан Gilad Naor 14 March 2012 в 13:42
поделиться

Нет никакого лучшего подхода, только общие и менее общие падежи.

более общий падеж - когда у Вас есть интерфейс класса/функции для объявления/определения. Лучше иметь только один .cpp/.c с определениями и одним заголовком для объявлений. Предоставление их, которых то же имя делает легким понять, что они непосредственно связаны.

, Но это не "правило", это - распространенный способ и самое эффективное почти во всех случаях.

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

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

1
ответ дан Klaim 14 March 2012 в 13:42
поделиться

Мне нравится помещать интерфейсы в заголовочные файлы и реализацию в cpp файлах. Мне не нравится писать C++, где я должен добавить членские переменные и прототипы к заголовку и затем методу снова в C++. Я предпочитаю что-то как:

module.h

struct IModuleInterface : public IUnknown
{
    virtual void SomeMethod () = 0;
}

module.cpp

class ModuleImpl : public IModuleInterface,
                   public CObject // a common object to do the reference
                                              // counting stuff for IUnknown (so we
                                              // can stick this object in a smart 
                                              // pointer).
{
    ModuleImpl () : m_MemberVariable (0)
    {
    }

    int m_MemberVariable;

    void SomeInternalMethod ()
    {
        // some internal code that doesn't need to be in the interface
    }

    void SometMethod ()
    {
        // implementation for the method in the interface
    }

    // whatever else we need
};

я нахожу, что это - действительно очевидный способ разделения реализации и интерфейса.

2
ответ дан RedBlueThing 14 March 2012 в 13:42
поделиться

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

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

, Поскольку другие сказали, если нет ничего в cpp файле, который стоит представить другим частям кода, поскольку обычно имеет место с main.c, то нет никакой потребности в заголовочном файле.

иногда стоит поместить все, что Вы хотите представить в единственном заголовочном файле (например, Func1and2and3.h), так, чтобы что-либо, что знает о Func1, знало о Func2 также, но я лично не увлечен этим, поскольку это означает, что Вы склонны загружать адскую партию спама наряду с материалом, который Вы на самом деле хотите.

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

1
ответ дан deworde 14 March 2012 в 13:42
поделиться

Обычно будет один.h файл для каждого .c/.cpp файла.

3
ответ дан Trent 14 March 2012 в 13:42
поделиться

Обычно файлы cpp/c для реализации, и h/hpp (hpp часто не используются), файлы для заголовочных файлов (только прототипы и объявления). Файлам Cpp нужно было не всегда связывать заголовочный файл с ним, но это обычно делает как действия заголовочного файла как мост между cpp файлами, таким образом, каждый cpp файл может использовать код из другого cpp файла.

Одной вещью, которая должна быть сильно осуществлена, является нет смысла в коде в заголовочном файле! Был слишком много раз, где заголовочные файлы повреждают компиляции в любом проекте размера из-за переопределений. И это просто, когда Вы включаете заголовочный файл в 2 различных cpp файла. Заголовочные файлы должны всегда разрабатываться, чтобы быть включенными многократно также. Файлы Cpp никогда не должны включаться.

0
ответ дан Jeremy Edwards 14 March 2012 в 13:42
поделиться

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

то, Что я имею в виду, следующее: a. пара cpp/.h файлов в значительной степени, что все "модули" заканчиваются так или иначе. Создание существующего из требования сохраняет много беспорядка и плохой разработки.

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

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

Так: всегда определяйте и.h и.c файлы. Сделайте это стандартом, следуйте, это, и безопасно полагается на него. Жизнь намного более проста этот путь, и простота самая важная вещь в программном обеспечении.

6
ответ дан 14 March 2012 в 13:42
поделиться

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

4
ответ дан Khoth 14 March 2012 в 13:42
поделиться

Это зависит. Обычно Ваша причина того, чтобы иметь отдельные.c файлы будет диктовать, должны ли Вы разделить.h файлы.

2
ответ дан jmucchiello 14 March 2012 в 13:42
поделиться
  1. Заголовочные файлы не обязательны.

  2. #include просто скопировать/вставить безотносительно включенного файла (включая.c исходные файлы)

  3. Наиболее часто используемый в реальных проектах глобальные заголовочные файлы как config.h и constants.h, который содержит наиболее часто используемую информацию, такую как флаги времени компиляции и широкие константы проекта.

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

  5. здравый смысл Использования. C/C++ не действительно для тех без него.

10
ответ дан Anders Hansson 14 March 2012 в 13:42
поделиться