Включать header файлы в .cpp, а не .h

75
06 марта 2022, 20:10

Какое преимущество в билде от того, что header файлы будут включены в .cpp, а не .h? Как это влияет на время билда и какие в этом плюсы и минусы?

Раньше считал, что header должны по всем канонам включаться только в заголовочные файлы. (как вариант для того, чтобы .cpp файл оставался чистым, а все импорты можно было видеть в одном месте)

Пример:

A.h:

inline void in_func(){}

B.h

#include "A.h" ???
class B {
public: 
  void func();
};

B.cpp:

#include "B.h"
#include "A.h" ??? 
void B::func()
{
  in_func();
}
Answer 1

Простой пример:

Допустим у вас, в заголовочном файле, есть прототип некой функции:

void foo(const std::string&);

И пусть в cpp. определяете так:

 void foo(const std::string& str)
{
    std::istringstream is(str);
    std::set<char> s;
    //...
} 

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

Answer 2

Разумеется будет преимущество в скорости сборки, если включать заголовочники в cpp. Так как если их включать только в другие заголовочники, то будет много лишних включений. Один заголовок включится в другой, этот другой включится еще в пять, эти пять еще в десять и так далее, пока не получится, что все заголовки включены во все заголовки. При этом скорость сборки снизится от того, что:

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

На самом же деле, включать заголовочники в cpp нужно не столько для ускорения сборки, сколько для разграничения видимости и структурирования. На практике, желательно, чтобы сущности имели как можно менее узкую область видимости, в идеале, только там где нужно. Так ими легче управлять. А область видимости в Си++ управляется, в первую очередь, с помощью заголовочников. В процессе разработки, если возникла потребность во включении какого-то заголовочника, спешить не надо, нужно посмотреть почему эта потребность возникла, может проект структурирован не совсем удачно.

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

READ ALSO
Передать по jqery в laravel

Передать по jqery в laravel

подскажите пожалуйста Есть views и контроллер Как передать переменную в контроллер ,выполнить запрос и вернуть его в views К примеру по клике...

73
Как вывести в div результат ajax?

Как вывести в div результат ajax?

Получаю ответ в json от ajax запроса и пытаюсь вывести в <div class="writeinfo"></div>

101
Переменная становится undefined внутри else

Переменная становится undefined внутри else

Всем приветВот часть моего кода в jquery

108
jquery удалить обработчик события

jquery удалить обработчик события

Решил недавно заюзать для сайта pjax

103