Заголовок в исходном файле
Я пытаюсь понять цель за одним заголовком для каждого метода исходного файла. Как я вижу, заголовки предназначены для совместного использования деклараций функций, typedef
и макросов между несколькими файлами, которые их используют. Когда вы создаете файл заголовка для вашего .c
файла, у него есть недостаток: каждый раз, когда вы хотите увидеть объявление функции или макрос, вам нужно обратиться к файлу заголовка, и, как правило, проще, что все находится в одном исходном файле (не все программное обеспечение, конечно).
Итак, почему программисты используют этот метод?
- Как я могу заставить Makefile автоматически пересобирать исходные файлы, содержащие модифицированный заголовочный файл? (В C / C ++)
- Объявление переменной в файле заголовка
- Где Visual Studio ищет файлы заголовков C ++?
- Инструмент для отслеживания зависимостей #include
- Каковы преимущества относительного пути, например «../include/header.h» для заголовка?
- Вперед объявить контейнер STL?
- Заголовок ответа jQuery и AJAX
- Использование анонимных пространств имен в файлах заголовков
- Заглавийте первую букву обоих слов в строке из двух слов
- В чем разница между .cpp-файлом и файлом .h?
- Заголовок диапазона HTTP
- GridView - отображать заголовки на пустом источнике данных
- * .h или * .hpp для определения classов
Заголовочные файлы в C отдельных декларациях (которые должны быть доступны для каждого файла .c, который использует функции) из определений (которые должны быть в одном месте). Кроме того, они обеспечивают небольшую модульность, поскольку вы можете поместить только публичный интерфейс в заголовочный файл и не указывать функции и статические переменные, которые должны быть внутренними для файла .c. Это использует файловую систему для обеспечения публичного интерфейса и частной реализации.
Практика одного файла .h в один .c файл в основном удобна. Таким образом, вы знаете, что объявления находятся в файле .h и определениях в соответствующем .c файле.
Логическая, структурированная организация и небольшие исходные файлы позволяют:
- более быстрое и лучшее программирование – разбиение кода на более управляемые и понятные fragmentы облегчает поиск, понимание и редактирование соответствующего кода.
- повторное использование кода – разные «модули» кода могут быть разделены на группы исходных / заголовочных файлов, которые можно более легко интегрировать в разные программы.
- лучше «инкапсуляция» – только файлы .c, которые специально include этот заголовок, могут использовать функции из него, что позволяет свести к минимуму отношения между различными частями вашего кода, что способствует модульности. Это не мешает вам использовать вещи из любого места, но это помогает вам задуматься о том, почему конкретному файлу c требуется доступ к функциям, объявленным в определенном заголовке.
- Помощь в совместной работе – два программиста, пытающихся одновременно изменить один и тот же файл кода, обычно вызывают проблемы (например, исключительные блокировки) или дополнительную работу (например, слияние кода), которые замедляют друг друга.
- быстрее компилирует – если у вас есть один заголовок, то каждый раз, когда вы вносите изменения, вы должны перекомпилировать все. Со многими небольшими заголовками необходимо перестроить только файлы .c, которые # include измененный заголовок.
- упрощенная ремонтопригодность и рефакторинг – по всем вышеперечисленным причинам
В частности, «один заголовок для каждого исходного файла» позволяет легко находить объявления, относящиеся к файлу c, в котором вы работаете. Как только вы начинаете объединять несколько заголовков в один файл, становится трудно связать файлы c и h, и в конечном итоге значительно затрудняет создание большого приложения. Если вы работаете только с небольшим приложением, то по-прежнему неплохо привыкнуть к масштабируемому подходу.
Потому что, как вы сказали сами, невозможно поставить «все программное обеспечение» в один исходный файл.
Если ваша программа очень мала, то да, проще просто поместить все в один .c файл. По мере того, как ваша программа становится больше, становится полезным организовать вещи, объединяя связанные функции в разные файлы .c. Кроме того, в файлах .h вы можете ограничить объявления, которые вы даете объявлениям, которые должны использоваться вещами в других файлах .c. Если файл .c не содержит ничего, что должно быть доступно вне себя, ему не нужен заголовок.
Например, если .c имеет функцию foo () и fooHelper (), но никто, кроме foo (), не должен напрямую вызвать fooHelper (), то, помещая foo () и fooHelper () в foo.c, foo () в foo.h и объявляя fooHelper () как статический, это помогает обеспечить, чтобы другие части вашей программы должны были обращаться к foo () и не должны знать или заботиться о fooHelper (). Вид не объектно-ориентированной формы инкапсуляции.
Наконец, сделать двигатели, как правило, достаточно умными, чтобы пересобирать только те файлы, которые были изменены с момента последней сборки, поэтому разделение на несколько файлов .c (с использованием файлов .h для совместного использования того, что нужно для совместного использования) помогает ускорить сборку.
Вы только помещаете в свой заголовочный файл минимальный минимум, чтобы другие исходные файлы должны были «видеть» для компиляции. Я видел некоторых людей, которые помещали все некоды в заголовочный файл (все typedefs, все # define, все структуры и т. Д.), Даже если в кодовой базе ничего не будет использовать. Это значительно затрудняет чтение файла заголовка для себя и тех, кто хочет использовать ваш модуль.
Программисты используют этот метод, потому что он позволяет им отделять интерфейс от реализации , гарантируя, что клиентский код и реализация согласуются с декларациями функций . Файл .h является «единственной точкой истины» (см. «Не повторяйте себя») о прототипе каждой функции.
(Код клиента – это код, который #include
– файл .h, чтобы использовать экспортированные функции, но не выполняет никаких функций в .h.)
Вам не нужен один заголовок для исходного файла. Один заголовок на модуль, содержащий открытый интерфейс, и, возможно, дополнительный заголовок, содержащий приватные объявления и т. Д., Разделяемый между файлами в этом модуле.
Как правило, заголовок для метода исходного файла означает, что вы объявляете только функции из этого модуля компиляции в этом заголовке.
Таким образом, вы не загрязняете декларациями, которые вам не нужны. (в большом программном проекте может быть проблема)
Что касается отдельных блоков компиляции, они ускоряют компиляцию и могут помочь вам избежать столкновений, если частные символы объявлены статическими.