Причина [1] Более быстрое время компиляции
Не в моих проектах: исходные файлы (CPP) включают только заголовки (HPP), которые им нужны. Поэтому, когда мне нужно перекомпилировать только один CPP из-за незначительного изменения, у меня в десять раз больше файлов, которые не перекомпилированы.
Возможно, вам следует разбить ваш проект на более логичные источники / заголовки: модификация в реализации класса A НЕ должна требовать перекомпиляции реализаций классов B, C, D, E и т. Д.
Причина [2] Избегает циклических зависимостей
Круговые зависимости в коде?
Извините, но я еще не сталкивался с такой проблемой, потому что это реальная проблема: скажем, A зависит от B, а B зависит от A:
struct A
{
B * b ;
void doSomethingWithB() ;
} ;
struct B
{
A * a ;
void doSomethingWithA() ;
} ;
void A::doSomethingWithB() { /* etc. */ }
void B::doSomethingWithA() { /* etc. */ }
Хороший способ решения проблемы - разбить этот источник по крайней мере на один источник / заголовок на класс (способом, аналогичным способу Java, но с одним источником и одним заголовком на класс):
// A.hpp
struct B ;
struct A
{
B * b ;
void doSomethingWithB() ;
} ;
.
// B.hpp
struct A ;
struct B
{
A * a ;
void doSomethingWithA() ;
} ;
.
// A.cpp
#include "A.hpp"
#include "B.hpp"
void A::doSomethingWithB() { /* etc. */ }
.
// B.cpp
#include "B.hpp"
#include "A.hpp"
void B::doSomethingWithA() { /* etc. */ }
Таким образом, нет проблем с зависимостями, и все еще быстрое время компиляции.
Я что-то пропустил?
При работе над "реальными" проектами
в реальном проекте файлы cpp имеют тенденцию включать случайные заголовки, пока вы не сможете выяснить, кто от кого зависит
Конечно. Но затем, если у вас есть время для реорганизации этих файлов, чтобы создать ваше решение «один CPP», тогда у вас есть время, чтобы очистить эти заголовки. Мои правила для заголовков:
- разбить заголовок, чтобы сделать его как можно более модульным
- Никогда не включайте заголовки, которые вам не нужны
- Если вам нужен символ, объявите его заранее
- только если вышеперечисленное не удалось, включите заголовок
В любом случае, все заголовки должны быть самодостаточными, что означает:
- Заголовок включает все необходимые заголовки (и только необходимые заголовки - см. Выше)
- пустой файл CPP, включающий один заголовок, должен компилироваться без необходимости включать что-либо еще
Это устранит проблемы с порядком и круговые зависимости.
Является ли время компиляции проблемой? Тогда ...
Если время компиляции действительно является проблемой, я бы подумал:
- Использование предварительно скомпилированных заголовков (это очень полезно для STL и BOOST)
- Уменьшите связь через идиому PImpl, как описано в http://en.wikipedia.org/wiki/Opaque_pointer
- Использовать общую сетевую компиляцию
Заключение
То, что вы делаете, не помещает все в заголовки.
Вы в основном включаете все свои файлы в один и только один конечный источник.
Возможно, вы выиграли с точки зрения полной компиляции проекта.
Но при компиляции для одного небольшого изменения вы всегда проиграете.
При кодировании я знаю, что часто компилирую небольшие изменения (если только компилятор проверяет мой код), а затем в последний раз выполняю полное изменение проекта.
Я бы потерял много времени, если бы мой проект был организован по-вашему.