Поскольку обычно заголовки содержат объявления, а исходные файлы содержат реализацию, люди понимают, что заголовки являются интерфейсами, публикуются c API, а исходные файлы содержат детали реализации. Это еще более подтверждается тем фактом, что в библиотеке пользователь (потребитель библиотеки) не видит содержимое исходных файлов, но может видеть заголовки.
Однако это неверно:
Заголовки
- содержат определения (шаблоны, встроенные функции и переменные), заголовки
- содержат объявления членов закрытого класса и символы с внутренней связью (stati c нелокальные и анонимные пространства имен). Это явно не является частью API.
- библиотека предоставит символ (класс, функцию), даже если он используется исключительно внутри и не является частью API (если только он не используется только для один CU и выполненный с внутренней связью)
- заголовок библиотеки будет вносить в код потребителя весь заголовок, который он использует, даже если некоторые из этих заголовков не нужны для API библиотеки. Это внесет ненужные символы в код пользователя, загромождая пространства имен.
Разделение заголовков и исходных файлов не выполняется на барьере интерфейса / реализации publi c. Такое разделение кода - просто артефакт того, как спроектирован C ++ с его наследием C. C ++ не требует многопроходного компилятора, поэтому он требует объявления перед использованием и одного определения. Таким образом, заголовки являются решением для этого. Они не являются спецификациями API.
Поэтому неудачный вывод состоит в том, что в C ++ нет разделения API / реализации, и попытка использовать заголовки для этого будет безуспешной.
Теперь ответим на ваш вопрос: Известный мне идиоматический способ c - это использование пространства имен details
или impl
. Понятно, что пространства имен, названные таким образом, содержат детали реализации библиотеки и не должны использоваться в пользовательском коде. Лично я не изменил бы ваш первоначальный дизайн.
C ++ 20 наконец-то включает модули, которые afaik решает эту проблему. И теперь у нас есть четкое разделение внутренних символов, которые не будут видны потребителю по сравнению с публичным c API.