Какую структуру заголовка лучше всего использовать в библиотеке? - PullRequest
4 голосов
/ 09 апреля 2009

Что касается заголовков в библиотеке, я вижу два варианта, и я не уверен, что выбор действительно имеет значение. Скажем, я создал библиотеку, давайте назовем ее foobar. Пожалуйста, помогите мне выбрать наиболее подходящий вариант:

  1. Пусть один элемент будет включен в самый корень проекта библиотеки, давайте назовем его foobar.h, который включает все заголовки в библиотеке, такие как «src / some_namespace / SomeClass.h» и так далее. Затем из-за пределов библиотеки в файле, который я хочу использовать для работы с библиотекой foobar, просто #include <foobar.h>.

  2. У меня нет основного включения, и вместо этого включайте только те заголовки, которые нам нужны в местах, где я должен их использовать, поэтому у меня может быть целая куча включений в исходном файле. Поскольку я использую пространства имен, иногда такие глубокие, как 3, включая заголовки, кажется, немного хлопотно.

Я выбрал вариант 1 из-за простоты реализации. OpenGL и многие другие библиотеки, кажется, делают это, поэтому это казалось разумным. Однако стандартная библиотека C ++ может потребовать, чтобы я включил несколько заголовков в любой файл, почему у них не было только одного заголовочного файла? Если только я не идиот и они не отдельные библиотеки ...

Обновление:

В дополнение к ответам, я думаю, имеет смысл предоставить оба варианта, верно? Я был бы очень раздражен, если бы я хотел использовать std :: string, но должен был включать массу заголовочных файлов; это было бы глупо. С другой стороны, я был бы раздражен, если бы мне пришлось набирать массу #include строк, когда я все равно хотел использовать большую часть библиотеки.

Вперед заголовки:

Спасибо всем, кто посоветовал мне форвард-заголовки, это помогло мне сделать джунгли заголовков менее сложными! :)

Ответы [ 7 ]

6 голосов
/ 09 апреля 2009

stl, boost и другие, у которых есть много заголовочных файлов, которые предоставляют вам независимые инструменты, и вы можете использовать их независимо.

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

5 голосов
/ 09 апреля 2009

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

Как и в большинстве вопросов программирования, нет универсального ответа.

2 голосов
/ 09 апреля 2009

Все # включенные заголовки должны быть обработаны. Это не так плохо, как могло бы быть, поскольку современные компиляторы предоставляют какую-то опцию, чтобы не обрабатывать их повторно (возможно, с чем-то вроде #pragma once или ifndef guard). Тем не менее, каждый #included заголовок должен быть обработан один раз для каждой единицы перевода, и это может сложиться быстро.

Обычная практика заключается в том, чтобы заголовочные файлы #include только те заголовочные файлы, которые им нужны, и максимально использовали предварительные объявления (class foo;). Таким образом, вы не получите накладные расходы.

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

1 голос
/ 09 апреля 2009

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

1 голос
/ 09 апреля 2009

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

1 голос
/ 09 апреля 2009

Все включаемые файлы должны иметь собственный смысл. И вы должны выбрать структуру заголовка с позиций lib-users: как пользователи должны использовать мою библиотеку? какая структура будет лучше для пользователей?



Примеры:
если в вашей библиотеке предусмотрены строковые алгоритмы - лучше сделать один заголовок со всеми - string_algorithms.h;
если в вашей библиотеке есть какой-то один фасадный объект - лучше использовать один заголовочный файл (может быть, несколько других файлов с расширениями или помощниками); если вы предоставляете комплекс объектов, которые будут использоваться независимо, создайте разные заголовочные файлы (контейнеры lib предоставляют разные контейнеры);

1 голос
/ 09 апреля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...