Я недавно начал изучать make-файлы, и видео, которое я смотрю, включает в себя компиляцию двух исходных файлов и файла заголовка. Класс был определен в файле заголовка, который был включен в оба исходных файла. Метод для класса был определен в одном исходном файле и вызван во втором (main.cpp). Зачем мне нужно иметь 2 исходных файла (.c / .cpp)?
Зачем мне компилировать 2 исходных файла C / ++ вместо использования файла заголовка?
Ответы (2)
Человеческий разум не может одновременно удерживать очень много информации, поэтому мы разбиваем ее на более мелкие, логичные и последовательные части.
В ПОРЯДКЕ. Итак, один main.cpp, который включает в себя десятки, сотни или тысячи файлов в программе, все они реализованы в файлах заголовков разумного размера, каждый из которых охватывает одну концепцию или объединяет несколько файлов заголовков, если одна концепция слишком широка, чтобы ее можно было легко описать < sup> 1 в одном заголовке. Проблема решена, да? Ага. Но это только одна проблема.
А как насчет потребления ресурсов?
Перед этим полезно ознакомиться с Как работает процесс компиляции / связывания? продолжая.
Во время предварительной обработки каждый оператор include заменяется содержимым включенного файла. В результате в компилятор загружается гигантский файл. Это занимает много памяти. Кроме того, если один файл включает в себя все в виде заголовков, то каждый раз, когда вы вносите изменения, независимо от их размера, необходимо будет создать этот файл. Он будет включать в себя заголовки проекта, и это одно изменение приведет к перекомпиляции ВСЕХ файлов. На это уходит очень много времени.
Память продолжает дешеветь, поэтому ограничение первого ресурса не так важно, как это было в 1970-х годах, когда все это изобреталось 2. По-прежнему время от времени поднимает свою уродливую голову. Вот почему я компилирую кросс-компиляцию на большом и толстом ПК, а не пишу код непосредственно на Raspberry Pi.
Время не дешевеет. Никогда не было и не будет.
Но если вы будете следовать лучшим практикам и заголовки содержат интерфейс (что он делает), а не реализацию (как он это делает), вы обнаружите, что заголовок не сильно меняется. В большинстве случаев меняются инструкции в файлах реализации. Небольшое изменение ограничено одним файлом реализации, который обеспечивает это измененное поведение. Скорее всего, это единственный файл, который нужно перекомпилировать. Это огромное улучшение по сравнению с каждым файлом каждый раз до одного или двух файлов каждый раз.
В редких случаях, когда интерфейс меняется, ну, вы терпите.
1 Потому что это и есть код: описание поведения. Это не список инструкций для выполнения компьютером - это вывод компилятора - это описание поведения программы. Задача компилятора - превратить ваше описание в инструкции.
2 Это также объясняет, почему создание на недавно созданных языках намного проще 3. У них не осталось лишнего багажа, чтобы заставить все работать в славные дни 1/2 КБ оперативной памяти и процессоры с тактовой частотой в килогерцах. Они также извлекли уроки из множества ошибок.
3 В любом случае для конечного пользователя. Бэкэнд современной системы сборки - это какой-то сумасшедший код, чувак.
Каждый раз, когда вы вносите какие-либо изменения в файл заголовка, каждый файл, который включает его, должен быть перекомпилирован, но если вы изменяете исходный файл только, этот исходный файл необходимо перекомпилировать.
При работе над проектом нетривиального размера это может значительно сократить время компиляции. Поскольку большая часть вашей работы обычно выполняется на стороне реализации, где изменения в файлах заголовков происходят реже, чем в исходных файлах, большая часть перекомпиляции будет локализована.
Вы также захотите разделить исходный код на отдельные файлы для удобства навигации. Работа с исходным файлом из 2000+ строк намного сложнее, чем с 10 файлами по 200 строк каждый. Это даже более важно, когда срабатывает контроль версий, и вы работаете в команде, поскольку тогда конфликты слияния уменьшаются.
Представьте, что Chrome был бы просто отдельным .cpp
файлом. Внесение даже самых тривиальных изменений потребовало бы перекомпиляции всего этого, что даже на хорошо оборудованной машине займет 6-12 часов. Для сравнения, компиляция единого исходного файла и повторная компоновка занимают несколько минут.
На практике у вас часто будет один класс на исходный файл с соответствующим файлом заголовка. Функции логически сгруппированы в наборы, каждый в своей паре заголовочный / исходный файлы.
main
, оба файла будут компилироваться, но компоновщик не может выбрать, какой из них использовать. - person user4581301   schedule 04.07.2020