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

Организация включает

  • Есть ли какой-то предпочтительный способ организации, включая директивы?
  • Лучше ли включать файлы, которые вам нужны, в файл .cpp вместо файла .h? Как-то повлияли единицы перевода?
  • Как насчет необходимости в файле .h и .cpp, следует ли просто включить его в файл .h? Это будет иметь значение?
  • Хорошо ли хранить уже определенные файлы в предварительно скомпилированном заголовке (stdafx.h), например, std и сторонние библиотеки? Как насчет моих собственных файлов, следует ли включать их в файл stdafx.h по мере их создания?

// myClass.h
#include <string>
// ^-------- should I include it here? --------

class myClass{
    myClass();
    ~myClass();

    int calculation()
};

// myClass.cpp
#include "myClass.h"
#include <string>
//  ^-------- or maybe here?  --------

[..]

int myClass::calculation(){
    std::string someString = "Hello World";
    return someString.length();
}


// stdafx.h
#include <string.h>
// ^--------- or perhaps here, and then include stdafx.h everywhere? -------
4b9b3361

Ответ 1

  • Вы должны иметь их в верхней части файла, все в одном месте. Это то, чего все ждут. Кроме того, полезно, чтобы они были сгруппированы, например. сначала все стандартные заголовки, затем сторонние заголовки (сгруппированные по библиотеке), а затем ваши собственные заголовки. Соблюдайте этот порядок во всем проекте. Это упрощает понимание зависимостей. Как отмечает @James Kanze, также полезно поместить заголовок, который сначала объявит содержимое. Таким образом, вы убедитесь, что он работает, если он включен первым (это означает, что он не зависит от того, включает ли он сам себя).
  • Держите область как можно меньше, так что изменение заголовка влияет на наименьшее количество единиц перевода. Это означает, что по возможности включайте его только в cpp файл. Как прокомментировал @Pedro d'Aquino, вы можете уменьшить количество включений в заголовке, используя по возможности прямые декларации (в основном, когда вы используете только ссылки или указатели для данного типа).
  • Оба - явно лучше, чем неявные.
  • После некоторого чтения я считаю, что вы должны включать только заголовки в PCH, если вы уверены, что они больше не меняются. Это касается всех стандартных заголовков, а также (возможно) сторонних библиотек. Для ваших собственных библиотек вы являетесь судьей.

Ответ 2

Эта статья о Файл заголовка включает шаблоны, должен быть полезен для вас.

  • Есть ли какой-то предпочтительный способ организации, включающий директивы?

Да, вы можете найти их в приведенной выше статье.

  • Лучше ли включать файлы, которые вам нужны в .cpp файле, а не файл .h? Являются ли единицы перевода как-то повлияло?

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

  • Как насчет того, если мне это нужно в файле .h и .cpp, я должен просто включить его в файл .h? Будет ли он дело?

Только в .h файле, но предлагается переслать объявление в файлы заголовков и включить в .cpp файлы.

  • Хорошо ли хранить уже определенные файлы в предварительно скомпилированном header (stdafx.h), например std и сторонних библиотек? Как насчет мои собственные файлы, я должен включить их в файл stdafx.h по пути, как я создать их?

Я лично не использовал предварительно скомпилированные заголовки, но раньше они обсуждались в Stackoverflow:

Предварительно скомпилированные заголовки? Нам они действительно нужны

Ответ 3

Есть ли какой-то предпочтительный способ организации, включая директивы?

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

Лучше ли включать файлы, которые вам нужны, в файл .cpp вместо файла .h?

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

Насколько повлияли единицы перевода?

В семантическом смысле, нет.

Как насчет того, нужно ли мне это как в файле .h, так и в файле .cpp, следует ли просто включить его в файл .h? Это будет иметь значение?

Просто включите его в заголовок.

Хорошо ли хранить уже определенные файлы в предварительно скомпилированном заголовке (stdafx.h), например, std и сторонние библиотеки? Как насчет моих собственных файлов, следует ли включать их в файл stdafx.h по мере их создания?

Предварительно скомпилированные заголовки могут значительно сократить время компиляции. Например: один из моих проектов, включающий boost::spirit::qi, компилируется за 20 секунд с PCH и 80 секунд - без. В общем случае, если вы используете некоторую библиотеку с большим количеством шаблонов, например boost, вам нужно использовать преимущество PCH.

Что касается вопроса в вашем примере кода:, поскольку вы не используете std::string в заголовке, лучше включить его в файл .cpp. Это хорошо для #include <string> в stdafx.h тоже, но это просто добавит немного сложности вашему проекту, и вы вряд ли заметите ускорение компиляции.

Ответ 4

(4) Я бы не рекомендовал включать любые дополнительные файлы в stdafx.h. или подобных файлов "include_first.h". Прямое включение в файлы cpp или конкретные h позволяет явно выражать зависимости вашего кода и исключать избыточные зависимости. Особенно полезно, когда вы решили разложить монолитный код на несколько библиотек или dll. Лично я использую файлы, такие как "include_first.h" (stdafx.h) только для целей конфигурации (этот файл содержит только определения макросов для текущей конфигурации приложения).
Можно предоставить предварительно скомпилированные заголовки для ваших собственных файлов, пометив другой файл, чтобы остановить прекомпиляцию вместо stdafx.h(например, вы можете использовать специальный пустой файл с именем "stop_pch.h" ).
Обратите внимание, что предварительно скомпилированные заголовки могут не работать должным образом для некоторых видов сложного использования препроцессора (особенно для некоторых техник, используемых в BOOST_PP_ *)

Ответ 5

С точки зрения производительности:

Изменение любого из заголовков, включенных в stdafx.h, вызовет новую предварительную компиляцию, поэтому это зависит от того, как "заморожен" код. Внешние библиотеки являются типичными кандидатами для включения stdafx.h, но вы также можете включить свои собственные библиотеки - это компромисс, основанный на том, как часто вы планируете их изменить.

Кроме того, с компилятором Microsoft вы можете поместить это в начало каждого файла заголовка:

#pragma once

Это позволяет компилятору полностью пропустить этот файл после первого вхождения, сохраняя операции ввода-вывода. Традиционный шаблон ifndef/define/endif требует открытия и разбора файла каждый раз, когда он включается, что, конечно, занимает некоторое время. Это, безусловно, может накапливаться и становиться заметным!

(Удостоверьтесь, что там остались традиционные охранники, для переносимости.)

Ответ 6

Возможно, важно заметить, что порядок классов в модуле перевода должен быть правильным или некоторые функции С++ просто отключены и приводят к ошибке времени компиляции.

Изменить: Добавление примеров:

class A { };
class B { A a; }; // order of classes need to be correct