Связывание C ++ с методами, определенными в определении класса - PullRequest
4 голосов
/ 03 июня 2011

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

Ответы [ 3 ]

4 голосов
/ 03 июня 2011

Размещается ли он в каждом файле .obj, который содержит заголовок, а затем на этапе компоновщика выбрасываются дополнительные копии? См. Эту статью.

3 голосов
/ 03 июня 2011

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

1 голос
/ 03 июня 2011

Если компилятор отклоняет встраивание какой-либо функции-члена, которая встроена в тело класса или определяется как inline функция вне тела класса, компилятор вставит скомпилированную версию функции в каждый файл .obj, который использует эту функцию. Обратите внимание, что это отличается от вставки скомпилированной версии каждой функции, объявленной в заголовке. Файл, о котором идет речь, должен вызывать эту (предположительно) встроенную функцию.

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

...