@Yonghwa
121

Как линкуются .cpp файлы к файлам .h?

Есть file.h, где просто описан класс.
Есть file.cpp, где описана реализация этого класса.

в main.cpp, в main, я создаю объект класса file, предварительно подключив "file.h".
Как он понимает, что реализация в file.cpp?

По логике, я подключаю просто header, где прототипы, а о том, что реализация в cpp, нет никаких данных для файла file.h.
  • Вопрос задан
  • 2182 просмотра
Пригласить эксперта
Ответы на вопрос 3
gbg
@gbg Куратор тега C++
Любые ответы на любые вопросы
Компоновщик ищет не файл с реализацией, а метод (на самом деле, это называется "символ") с соответствующим именем.

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

Если в двух объектных файлах найдется одинаковый символ, компоновщик будет ругаться. В *.h компоновщик не смотрит.
Ответ написан
Комментировать
@abcd0x00
Как он понимает, что реализация в file.cpp?

Очень просто: ты подаёшь этот файл компилятору, а всё, что в нём есть, попадает в общее глобальное пространство. После обработки препроцессором всё это выглядит так, будто оно не в нескольких файлах, а в одном.

В итоге, file.h file.cpp main.c становятся как бы одним файлом.
Ответ написан
@elmm
Несколько уточню ситуацию. Сначала идёт компиляция всех c/cpp (и не только - что укажешь компилятору) файлов. При компиляции по исходнику проходит препроцессор и на место #include подставляет содержимое подключаемых файлов. Таким образом и main.cpp и file.cpp будут содержать вначале file.h с описанием класса. На выходе для каждой единицы компиляции класса получается объектный файл с скомпилированным кодом, где вместо адресов функций указывается какую функцию надо поставить при линковке (модифицированное компилятором имя функции, отражающее перечень аргументов ф-ции, способ вызова и прочее см. name mangling).

При линковке все указанные обьектные файлы, библиотеки (просто контейнер для обьектых файлов) собираются в один исполняемые файл - вот тут уже линкер и находит что из main.obj из некой функции вызывается фйнкция, из file.obj, и подставляет нужный вызов.

По сути .h файлы это сахар, что-бы много раз не писать в каждом компилируемом модуле forward declaration чего либо, и компилятор вообще может ни чего не знать о существовании тех же .h файлов, если препроцессор реализован как отдельная программа (см. больше про C препроцессор).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы