Каковы недостатки использования заголовков C ++ (.h) и заголовков плюс реализация (.h + .cpp)? - PullRequest
6 голосов
/ 10 ноября 2010

Как начинающий программист C ++, я всегда помещал свой интерфейс классов в файлы .h, а реализацию в файлы .cpp. Однако недавно я пробовал C # некоторое время, и мне очень нравится его чистый синтаксис и способ организации файлов, в частности, нет различий между заголовками и реализацией, вы обычно реализуете класс для каждого .cs файла и вам не нужен заголовки.

Я знаю, что в C ++ это также возможно (вы можете кодировать «встроенные» функции в .h файлах), но до сих пор я всегда видел четкое различие между .h и .cpp файлами в проектах C ++ , Каковы преимущества и недостатки этого подхода?

Спасибо

Ответы [ 9 ]

9 голосов
/ 10 ноября 2010

В C ++ есть несколько способов разделить две справки. Во-первых, если вы хотите обновить библиотеку без изменения интерфейса, то наличие кода в файле C ++ означает, что вы можете просто обновить библиотеку, а не библиотеку плюс заголовки. Во-вторых, это скрывает реализацию. То есть это заставляет людей смотреть на ваш класс только с точки зрения интерфейса, что должно их беспокоить, если код хорошо написан. Наконец, в этом разделении есть что-то вроде эстетической чистоты с интерфейсом и документацией. К этому нужно привыкнуть, но через некоторое время это станет естественным (мнение.)

5 голосов
/ 10 ноября 2010

Не забывайте время сборки.

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

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

Мое эмпирическое правило: храните объявления в файлах .H, сохраняйте определения в файлах .CPP.

2 голосов
/ 10 ноября 2010

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

1 голос
/ 10 ноября 2010

В недавнем крупном проекте авторы систем, которые я хотел использовать, поместили много кода в файлы .h. Включая их файлы .h в мой собственный источник, он добавил дополнительные зависимости в мой файл. После включения зависимостей для их проекта я столкнулся с коллизиями typedef. Если бы они разделили код и поместили объявления только в файл .h, это было бы намного проще. Я предлагаю использовать типы posix и помещать объявления только в файлы .h.

1 голос
/ 10 ноября 2010

Я бы повторил @wheaties и добавил бы еще несколько пунктов

  1. Компиляция проще (может быть, это только я), мне никогда не удавалось заставить компиляцию работать правильно, если вы изменили только заголовок (как и во всех файлах реализации, которые его включали). Я верю, что в Makefiles вы должны добавлять зависимости вручную, что является реальной болью в очень крупных проектах (опять же, это может быть только я). Так что если у вас есть код в файлах реализации, то изменения просто означают перекомпиляцию этого конкретного файла - очень полезно, когда вы хотите сделать быстрые изменения, собрать и протестировать.

  2. Позвольте мне еще раз повторить скрытый аспект, чаще всего вы не хотите, чтобы люди знали детали реализации из-за чувствительной природы кода, и, таким образом, открывали только заголовки плюс предварительно собранные библиотеки, и разделение является ключевым здесь.

  3. Форвардные объявления, хитрый трюк, в котором вам не нужно включать детали реализации класса в файл заголовка, если он не «используется» ни в одном коде в заголовке, а затем в реализации файл, который вы можете включать в себя настоящий заголовок и «все работает хорошо» (помогает, если у вас есть циклические зависимости - почему они у вас есть, другая проблема!)

1 голос
/ 10 ноября 2010

Интересно отметить, что в последнее время C #, похоже, в некоторой степени движется в направлении C / C ++, с введением частичных классов.

Особое преимущество этого в IDE заключается в том, что Visual StudioРазработчик изменит часть класса, которая работает с визуальными элементами управления или элементами данных, и их макет, не беспокоясь о путанице методов (логики приложения), которые находятся в отдельном файле.

1 голос
/ 10 ноября 2010

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

Кроме того, если вы объявляете вещи только внутри .h, вы не можете обмениваться переменными и структурами между другими .cpp файлами ..

0 голосов
/ 06 марта 2013

Что касается сравнения .cs против .cpp / .h Я думаю, вам нужно иметь в виду фон, ведущий архитектор C #: Андерс Хейлсберг В Delphi у вас также нет различия между заголовком и модулем (игнорирование включаемых файлов для этого обсуждения). У вас просто есть два раздела в файле модуля initialization и implementation.

Другие пункты уже упоминались.

0 голосов
/ 10 ноября 2010

Я вижу, что многие ответы выступают за разделение, в первую очередь из-за преимуществ времени сборки и скрытия реализации.И то и другое, безусловно, плюсы, хотя я расскажу о контрпримере: Boost .

В большинстве библиотек Boost используется файл .hpp без внешних ссылок.Причина в том, что это часто требуется в случае шаблонов, когда компилятор должен знать типы аргументов из вызывающей подпрограммы.Таким образом, у вас может не быть выбора, если вы хотите придерживаться «современного» подхода C ++ к сокращению классов для шаблонов.

...