Я не уверен, какой именно вопрос вы задаете, поэтому попытаюсь перефразировать его:
В чем преимущество размещения публичной информации в отдельном (заголовочном или интерфейсном) файле, в отличие от простой пометки информации как публичной или приватной везде, где она появляется?
Основное преимущество наличия отдельного интерфейса или заголовочного файла в том, что он снижает когнитивную нагрузку на читателя. Если вы пытаетесь понять большую систему, вы можете работать с одним файлом реализации за раз, и вам нужно читать только интерфейсы других реализаций/классов/модулей, от которых он зависит. Это большое преимущество, и языки, которые не требуют отдельных файлов интерфейсов (например, Java) или даже не могут выразить интерфейсы в отдельных файлах (например, Haskell), часто предоставляют такие инструменты, как Doxygen или Haddock, чтобы отдельный интерфейс для чтения генерировался из реализации.
Я предпочитаю такие языки, как Standard ML, Objective Caml и Modula-2/3, где есть отдельный файл интерфейса, доступный для изучения. Наличие отдельных заголовочных файлов в C также хорошо, но не совсем так хорошо, потому что в общем случае заголовочные файлы не могут быть проверены компилятором независимо. (Заголовочные файлы C++ менее хороши, потому что они позволяют частной информации, такой как частные поля или реализации встроенных методов, просачиваться в заголовочные файлы, и таким образом публичная информация становится размытой.)
В мире языкового дизайна существует фольклор, что для типичных статически типизированных языков только около 10% информации в модуле является публичной (измеряется строками кода). Вынося эту информацию в отдельный заголовочный файл, вы снижаете нагрузку на читателя примерно в десять раз.
Они используют некоторые идентификаторы, такие как общедоступные, частные, защищенные, для выполнения задач файлов заголовков.
Я думаю, что здесь вы ошибаетесь: например, в C ++ все еще есть public private и protected, но обычно разделяют реализацию из интерфейса с помощью файла заголовка (хотя это не относится к шаблонам функций).
Я думаю, что в целом неплохо отделять интерфейс от реализации при создании библиотек, поскольку тогда вы никогда не открываете внутреннюю работу чего-либо клиенту, и, таким образом, клиент никогда не сможет намеренно создать код, который зависит от реализации. . Выбор за вами. Должен признать, что для своего собственного кода (небольших программ, которые я пишу для себя) я использую его нечасто.
Они позволяют распространять API библиотеки, чтобы компилятор мог скомпилировать правильный код.
Как и в C, вместо того, чтобы включать всю реализацию, вы просто включаете определение того, что есть в библиотеке при компоновке .
В этом смысле преимущества в основном для компилятора. Следовательно, вы устанавливаете двоичную библиотеку, скажем, в / lib
, а заголовки - в свой путь поиска include. Вы говорите, что во время выполнения ожидайте, что эти символы с этим соглашением о вызовах будут доступны.
Когда они не требуются компилятору / компоновщику / интерпретатору, тогда соглашение для этого языка - лучший способ сделать это, потому что это то, что ожидают найти другие программисты. Ожидается обычный.
Такие языки, как C #, включают возможность проверять библиотеки на предмет информации из двоичного большого двоичного объекта, поэтому на многих из этих языков заголовки не требуются. Такие инструменты, как Cecil для C #, также позволяют вам самостоятельно проверять библиотеку (и даже изменять ее).
Короче говоря, некоторые языки лишены преимуществ заголовков и позволяют проверять библиотеку на предмет всей информации времени компиляции , необходимой для обеспечения соответствия кода компоновки одним и тем же спецификациям интерфейса / API.