Что должно войти в Ан.H-файл?



при разделении кода на несколько файлов только то, что именно должно идти в an .H файл и то, что должно войти в a .cpp файл?

548   12  

12 ответов:

файлы (.h) предназначены для предоставления информации, которая будет необходима в нескольких файлах. Такие вещи, как объявления классов, прототипы функций и перечисления, обычно входят в заголовочные файлы. Одним словом, "определения".

код файлов (.cpp) предназначены для предоставления информации о реализации, которая должна быть известна только в одном файле. В общем, тела функций и внутренние переменные, которые должны/никогда не будут доступны другим модулям, являются тем, что принадлежит .cpp файлы. Одним словом, "реализации".

самый простой вопрос, чтобы спросить себя, чтобы определить, что принадлежит где "если я изменю это, мне придется изменить код в других файлах, чтобы сделать вещи компилировать снова?"Если ответ "да", то он, вероятно, принадлежит к файлу заголовка; если ответ" нет", то он, вероятно, принадлежит к файлу кода.

дело в том, что в C++ это несколько сложнее, чем организация заголовка/источника C.

что видит компилятор?

компилятор видит один большой источник (.cpp) файл с правильно включенными заголовками. Исходный файл-это единица компиляции, который будет скомпилирован в объектный файл.

Итак, зачем нужны заголовки?

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

в этом случае, есть две копии одной и той же информации. Что является злом...

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

заголовки используются для размещения этих общих сведений.

переместите в заголовок объявления о том, что нужно разделить между несколькими источниками

больше ничего?

В C++ есть некоторые другие вещи, которые могут быть помещены в заголовок, потому что они тоже должны быть разделены:

  • код
  • шаблоны
  • константы (обычно те, которые вы хотите использовать внутри переключатели...)

переместить в заголовок все, что должно быть общим, включая общие реализации

означает ли это, что внутри заголовков могут быть источники?

да. На самом деле, есть много разных вещей, которые могут быть внутри "заголовка" (т. е. совместно используемых между источниками).

  • вперед деклараций
  • заявления/определение функции/структуры/классы/шаблоны
  • реализация встроенного и шаблонного кода

это становится сложным, а в некоторых случаях (круговые зависимости между символами), невозможно сохранить его в одном заголовке.

заголовки могут быть разбиты на три части

Это означает, что в крайнем случае, вы могли бы иметь:

  • заголовок прямого объявления
  • декларация/определение заголовок
  • заголовок осуществления
  • источник реализации

давайте представим, что у нас есть шаблонный MyObject. Мы могли бы:

// - - - - MyObject_forward.hpp - - - - 
// This header is included by the code which need to know MyObject
// does exist, but nothing more.
template<typename T>
class MyObject ;

.

// - - - - MyObject_declaration.hpp - - - - 
// This header is included by the code which need to know how
// MyObject is defined, but nothing more.
#include <MyObject_forward.hpp>

template<typename T>
class MyObject
{
   public :
      MyObject() ;
   // Etc.
} ;

void doSomething() ;

.

// - - - - MyObject_implementation.hpp - - - - 
// This header is included by the code which need to see
// the implementation of the methods/functions of MyObject,
// but nothing more.
#include <MyObject_declaration.hpp>

template<typename T>
MyObject<T>::MyObject()
{
   doSomething() ;
}

// etc.

.

// - - - - MyObject_source.cpp - - - - 
// This source will have implementation that does not need to
// be shared, which, for templated code, usually means nothing...
#include <MyObject_implementation.hpp>

void doSomething()
{
   // etc.
} ;

// etc.

Вау!

в" реальной жизни " это обычно менее сложно. Большинство кода будет иметь только простую организацию заголовка / источника, с некоторым встроенным кодом в источнике.

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

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

вывод

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

но в тот день, когда у вас будут циклические зависимости между шаблонными объектами, не удивляйтесь, если ваша организация кода станет несколько более "интересной", чем простой заголовок / источник организация...

^_^

в дополнение ко всем остальным ответам, я скажу вам, что вы не в заголовочный файл:
using объявление (наиболее распространенное существо using namespace std;) не должны появляться в заголовке файла, поскольку они загрязняют пространство имен исходного файла, в который он включен.

Что компилируется в ничто (нулевой двоичный след) переходит в файл заголовка.

переменные не компилируются в ничто, но объявления типов делают (потому что они только описывают, как ведут себя переменные).

функции не делают, но встроенные функции делают (или макросы), потому что они производят код только там, где вызывается.

шаблоны-это не код, это всего лишь рецепт для создания кода. поэтому они также идут в H-файлы.

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

этот вопрос и подобные ему часто задавались на SO-see почему есть заголовочные файлы и .cpp файлы в C++? и C++ Заголовочные Файлы, Разделение Кода например.

ваши объявления классов и функций плюс документация и определения для встроенных функций/методов (хотя некоторые предпочитают помещать их отдельно .мнз файлов).

в основном заголовочный файл содержит скелет класс или декларация (не часто меняются)

и cpp файл содержит реализация класса (часто меняется).

файл заголовка (.h) должно быть для объявлений классов, структур и их методов, прототипов и т. д. Реализация этих объектов производится в cpp.

in .h

    class Foo {
    int j;

    Foo();
    Foo(int)
    void DoSomething();
}

Я ожидал увидеть:

  • декларации
  • комментарии
  • определения отмечены inline
  • шаблоны

действительно ответ, хотя есть то, что не вставлять:

  • definitons (может привести к тому, что вещи умножаются)
  • использование деклараций / директив (заставляет их на всех, включая ваш заголовок, может вызвать nameclashes)

заголовок определяет что-то, но ничего не говорит о реализации. (Исключая шаблоны в этом "metafore".

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

  • вы определяете "макет" своей структуры, сообщая только столько, сколько необходимо окружающим группам использования.
  • определения переменной, функции и класс.

теперь я, конечно, говорю о первой подгруппе.

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

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

(.h)

  • макросы и включает в себя необходимые для интерфейса (как можно меньше)
  • объявление функций и классов
  • документация интерфейс
  • объявление встроенных функций / методов, если таковые имеются
  • extern к глобальным переменным (если таковые имеются)

Body (.cpp)

  • остальные макросы и включает в себя
  • включить заголовок модуль
  • определение функций и методов
  • глобальные переменные (если они есть)

Как правило, вы ставите " общую "часть модуля на.h (часть, которую должны видеть другие модули) и" не разделяемая " часть на.cpp

PD: Да, я включил глобальные переменные. Я использовал их несколько раз, и важно не определять их в заголовках, или вы получите много модулей, каждый из которых определяет свой собственный переменная.

изменить: изменено после комментария Дэвида

  • заголовочные файлы - не должны меняться во время разработки слишком часто -> вы должны думать, и писать их сразу (в идеальном случае)
  • исходные файлы-изменения во время реализации

Comments

    Ничего не найдено.