2012-03-27 2 views
0

Я только что получил мое первое настоящее приложение на C++ после работы с некоторыми книгами, изучающими язык. Насколько я понимаю, ваши исходные файлы cpp требовали сопроводительного заголовка, но одна из библиотек моего проекта прекрасно работает с несколькими файлами cpp, которые НЕ включают заголовок cooverponding. Этот конкретный cpp реализует класс, найденный в заголовке, который имеет другое имя и несколько других частей кода, помимо только первоначального объявления класса.Компиляция cpp без соответствующего заголовка

Как cpp может скомпилировать функции, принадлежащие классу, о котором он не знает?

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

Я ожидаю, что ответ может вызвать недоразумение в отношении процесса включения и компиляции, и я бы очень хотел изучить этот аспект C++. Спасибо!

+1

Файл заголовка в текстовом виде включен в блок переводов. Нет волшебства. Наоборот, заголовочные файлы - это поразительно грубые реликвии 1970-х годов. Вам вообще не нужны файлы заголовков, а не то, что это хорошая идея серьезно относиться к этой идее. Если у вас есть единица перевода, которая не предоставляет каких-либо функциональных возможностей другим участникам системы, тогда нет необходимости в заголовке. Хорошим примером может служить небольшая единица перевода, содержащая вашу функцию 'main'. –

+0

взгляните на это SO qn о компиляции и ссылках: http://stackoverflow.com/questions/6264249/how-does-the-compilation-linking-process-work – Sanish

ответ

2

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

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

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

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

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

0

Это несколько вопросов. Вы должны попытаться разбить их.

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

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

Смежные вопросы