исходный файл и заголовок в C ++ - PullRequest
3 голосов
/ 03 августа 2011

У меня есть вопрос об исходном файле и заголовке на c ++.

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

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

Ответы [ 4 ]

8 голосов
/ 03 августа 2011

Базовая модель компиляции , используемая (C и) C ++, таким образом:

  1. Вы помещаете объявлений , которые должны быть разделены между исходными файлами, в заголовочные файлы . Исходные файлы , которым требуется доступ к этим объявлениям, затем включают эти заголовочные файлы.
  2. При компиляции препроцессор (рекурсивно) заменит директивы #include с включенным файлом (-ами). Результат называется блоком компиляции .
  3. Затем компилятор компилирует эти единицы компиляции, по одному , в объектные файлы . (Примечание. Компилятор всегда видит только одну единицу перевода. Он не имеет доступа к тому, что объявлено и определено в других единицах перевода.) По сути, объектные файлы представляют собой готовый код, но все ссылки на символы (функции, переменные) вне их модуля компиляции все еще являются символическими.
  4. Затем компоновщик передает все объектные файлы и связывает ссылки на символы в этих объектных файлах с определениями символов , выплевывая исполняемый файл, если все идет хорошо.

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

Последствия этого:

  • Исходные файлы обычно содержат только заголовочные файлы.
    Поскольку вся магия препроцессора - это просто простой механизм замены текста без каких-либо знаний (C или) C ++ и его назначения в описанном выше процессе, его можно согнуть и использовать для других целей. При этом в том числе исходные файлы делались иногда для достижения какой-то цели. Но это редко.
  • Символы могут объявляться так часто, как это требуется, но они должны быть определены ровно один раз .
    Если компоновщик не может найти объявленный символ (и, следовательно, ссылки на него были приняты компилятором), он выдаст неприятное сообщение об ошибке в ваше лицо. Если он найдет несколько определений, он сделает то же самое.
  • Компилятору не важно, исходит ли объявление из заголовка, включенного препроцессором, или было записано непосредственно в исходный файл.
    Однако, если вы пишете объявления непосредственно в исходные файлы, компилятор, не имея возможности «просматривать» другие блоки перевода, не может предупредить вас, что они устарели. Если вместо этого вы помещаете объявления в заголовочные файлы, гораздо проще синхронизировать их с соответствующими определениями, и часто компилятор может даже диагностировать, если они не совпадают.
  • Любой проект с более чем одним исходным файлом может быть собран только несколькими прогонами компиляции (по одному для каждого исходного файла) с компоновщиком, связывающим результирующие объектные файлы. Однако часто IDE скрывают это за управлением своими проектами.
    Если вы измените заголовок, который прямо или косвенно используется во многих исходных файлах, вам придется перекомпилировать большую часть вашего проекта. Если вы измените исходный файл, вам нужно будет перекомпилировать только один исходный файл (и, разумеется, повторно связать исполняемый файл).
1 голос
/ 03 августа 2011

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

1 голос
/ 03 августа 2011

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

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

0 голосов
/ 03 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...