2010-12-25 1 views
6

Зачем использовать .cpp-файлы, если у меня есть весь код C++ в файле .h? Я имею в виду .cpp-файлы довольно странно использовать, если весь код можно написать в .h-файле? Может ли кто-нибудь сделать это?Зачем использовать .cpp-файлы, если у меня есть весь код C++ в файле .h?

ответ

7

Несколько причин:

(1) Инкрементальное время сборки

Когда проекты растут больше, управляя время сборки проблематично, особенно для проектов C++. Строительство 1 или 5 минут после незначительных изменений имеет большое значение. Это подчеркивается большинством изменений в крупных проектах, которые являются небольшими и требуют много испытаний. Добавьте к этому любую попытку TDD и рефакторинг, и вы мертвый слизник с сицилийскими ботинками.

Разделение на заголовок и тело и перемещение его в библиотеки улучшает инкрементное время сборки.

(2) статика
Для многих вещей, которые нужно один экземпляр типа, т.е.

// .cpp 
static Foo foo; 

Там нет никакого способа (что я знаю), что позволяет это в header- только проект. Конкретные решения для компилятора ограничены, например. __declspec(selectany) в MSVC ограничивается типами POD.

(3) Реализация скрывается
.cpp/.h разделение является единственным способом, чтобы четко отделить публичный интерфейс от деталей реализации. Вы можете бросить членов класса в раздел private, но это не работает для других объектов. (Даже разделение заголовка/тела негерметично, если вы не добавляете дополнительные методы, такие как PIMPL, поэтому этот аргумент немного слаб ИМО, но опять же, в большом проекте, я бы очень пропустил этот эффективный, если несовершенный метод).


Большой вопрос, так или иначе - вы признали, что есть что-то прервала с C/C++ построить модель, которую я считаю древнюю реликвию ужасных последствий.

Вы должны попробовать, как далеко вы можете нажать модель «только заголовок» (или, по крайней мере, «почти только заголовки», чтобы можно было использовать статику). Вы могли бы получить довольно далеко - также было бы интересно услышать от людей, которые пробовали.

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

+4

+1 для вызова модели сборки/ссылки C/C++, которая действительно довольно тяжелая –

2

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

+0

Я думаю, что это все равно можно сделать, вы можете включить публичный интерфейс в заголовки, которые включают «заголовки реализации», так же, как увеличение происходит с подпапками 'details \ '. Без интенсивного использования интерфейсов разделение .h/.cpp не очень хорошо сочетается с разделом интерфейса/реализации. – peterchen

3

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

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

Тогда есть стиль. Это просто выглядит неправильно. Но это вопрос предпочтения.

Тогда есть ссылки. Если ClassA использует ClassB, а ClassB использует ClassA, какой из них вы включите первым?

+0

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

+0

Ваше предположение о роли компоновщика и компилятора довольно устарело. Генерация кода с временным кодом широко используется уже десять лет. Небрежный способ его установки заключается в том, что с помощью LTCG компилятор является просто фантастическим препроцессором: файлы .obj на самом деле не содержат машинный код. И удаление дубликата (и ненужного, и т. Д.) Кода является данным. – martona

+0

все звуки очень умны - просто стыдно, что нужно справиться с устаревшей моделью сборки C/C++! –

Смежные вопросы