Подтвердить что ты не робот

Включить стратегию заказа файлов

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

Стандарты кодирования Google предлагают:

  • dir2/foo2.h(предпочтительное местоположение - см. подробности ниже).
  • C системных файлов.
  • Системные файлы С++.
  • Файлы других библиотек .h.
  • Ваши файлы проекта .h.

Неясно, какая разница между входами 1 и 5 выше и почему выбрано одно или другое местоположение. Тем не менее, другое онлайн-руководство предлагает этот порядок (найденный в разделе "Макет класса" этого документа):

  • включает
  • включает
  • local включает

Еще раз возникает двусмысленность, на этот раз между пунктами 2 и 3. В чем заключается различие? Включены ли эти объекты для межпроектных и внутрипроектных проектов?

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

4b9b3361

Ответ 1

Заказ, который вы указываете, включает в себя не обязательно с технической точки зрения. Если вы правильно ее разработали, вы сможете разместить их в любом порядке, и вы все равно будете работать. Например, если ваш foo.h нужен <string>, он должен быть включен в ваш foo.h, поэтому вам не нужно запоминать эту зависимость везде, где вы используете foo.

При этом, если у вас есть зависимости по заказу, большая часть времени, в течение которого ваш файл определения будет исправлена, исправит его. Это потому, что foo.h зависит от <string>, но не наоборот.

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

Ответ 2

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

Я сказал, что мои личные предпочтения ниже:

Для заголовков:

  • Заголовки С++
  • Заголовки сторонних разработчиков
  • другие заголовки проектов
  • Заголовки этого проекта

Источник:

  • предварительно скомпилированный файл заголовка
  • заголовок этого исходного файла
  • Заголовки С++
  • Заголовки сторонних разработчиков
  • другие заголовки проектов
  • Заголовки этого проекта

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

Ответ 3

Что касается стиля Google:

Нет никакой двусмысленности.

Первый заголовок, включенный в заголовок, должен быть заголовком, связанным с исходным файлом this, таким образом, в позиции 1. Таким образом вы убедитесь, что он включает в себя все, что ему нужно, и что нет "скрытой" зависимости: если есть, сразу же откроется и предотвратит компиляцию.

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

По определению заголовки систем C и С++ очень редко меняются, просто потому, что так много людей используют их, поэтому они становятся вторыми.

Код третьей стороны может быть изменен, но в целом он громоздкий и требует времени, поэтому они становятся третьими.

"Проект включает в себя" относится к общему объему, включая, как правило, домашние библиотеки (средние предметы), которые используются несколькими проектами. Их можно изменить, но это повлияет и на другие проекты, они станут четвертыми.

И, наконец, "local includes", то есть те файлы, которые являются конкретными для этого проекта и могут быть изменены без какого-либо влияния на кого-либо еще. В случае возникновения проблемы, это кандидаты в премьер-кандидаты, они на последнем месте.

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

В пределах данного слоя я стараюсь упорядочить их по алфавиту, потому что проще их проверить.