Подтвердить что ты не робот

Где "включить" включить в С++

Я читаю код С++ и замечаю, что есть "#include" как в файлах заголовков, так и в файлах .cpp. Я думаю, если я переведу все "#include" в файле, скажем, foo.cpp, тоже его "заголовочный файл foo.hh и пусть foo.cpp включает только foo.hh, код должен работать в любом случае без учета таких проблем, как недостатки, эффективность и т.д.

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

4b9b3361

Ответ 1

Как правило, поместите свои включенные в файлы .cpp, когда сможете, и только в файлах .h, если это невозможно.

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

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

Ответ 2

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

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

Включить загрязнение файлов, на мой взгляд, является одной из худших форм гниения кода.

Изменить: Хех. Похоже, что синтаксический анализатор ест > и < символы.

Ответ 3

Вы бы сделали все остальные файлы, включая файл заголовка, транзитным образом включили все #include в свой заголовок тоже.

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

Если вам нужно объявлять (но не определять) вещи в своем заголовке, используйте forward declaration вместо #include s.

Ответ 4

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

Ответ 5

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

Ответ 6

.hh(или .h) файлы должны быть для объявлений.

.cpp(или .cc) файлы должны быть для определений и реализаций.

Сначала убедитесь в том, что оператор #include является литералом. #include "foo.h" буквально копирует содержимое foo.h и вставляет его, когда директива include находится в другом файле.

Идея состоит в том, что некоторые другие файлы bar.cpp и baz.cpp могут захотеть использовать какой-то код, который существует в foo.cc. Обычно это делается для bar.cpp и baz.cpp для #include "foo.h", чтобы получить объявления о функциях или классах, которые они хотели использовать, а затем во время ссылки компоновщик подключил эти приложения в bar.cpp и baz.cpp для реализаций в foo.cpp(что вся точка компоновщика).

Если вы поместите все в foo.h и попытаетесь сделать это, у вас возникнет проблема. Скажем, что foo.h объявляет функцию с именем doFoo(). Если определение (код для) этой функции находится в foo.cc, это прекрасно. Но если код для doFoo() перемещается в foo.h, а затем вы включаете foo.h внутри foo.cpp, bar.cpp и baz.cpp, теперь есть три определения для функции с именем doFoo(), а ваш линкер будет жаловаться, потому что вам не разрешено иметь более одного объекта с тем же именем в той же области.

Ответ 7

Нет ничего плохого в использовании #include в файле заголовка. Это очень распространенная практика, вы не хотите обременять пользователя библиотекой, также помня, какие другие непонятные заголовки необходимы.

Стандартным примером является #include <vector>. Возвращает вам векторный класс. И плот внутренних заголовочных файлов CRT, которые необходимы для компиляции векторного класса, что вам действительно не нужно и не нужно знать.

Ответ 8

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

Ответ 9

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

(begin myheader.h)
#ifndef _myheader_h_
#define _myheader_h_
struct blah {};
extern int whatsit;
#endif //_myheader_h_

Теперь, если вы # включите "myheader.h" в другие файлы заголовков, он будет включаться только один раз (из-за определения _myheader_h_). Я считаю, что MSVC имеет "#pragma once" с эквивалентной функциональностью.