Страницы

Поиск по вопросам

пятница, 20 декабря 2019 г.

Директива pragma once

#cpp


Директива #pragma once распространяется на один подключаемый файл или на все?

UPDATE:
Понял, она распростаняется на сам файл. Тогда почему, когда я в файле указал #pragma
once и пытаюсь его подключить к другим файлам(нескольким) выдаются ошибки линковки:

1>error LNK2005: "void __cdecl logit(class std::basic_string,class
std::allocator >,int,class std::basic_string,class
std::allocator >)" (?logit@@YAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H0@Z)
already defined in file2.obj
1>error LNK2005: "class std::basic_string,class
std::allocator > __cdecl GetTime(void)" (?GetTime@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
already defined in file2.obj
1>error LNK2005: "void __cdecl GetDate(void)" (?GetDate@@YAXXZ) already defined in
file2.obj
1>fatal error LNK1169: one or more multiply defined symbols found

    


Ответы

Ответ 1



Вы неверно понимаете эту директиву. Она распространяется на файл, в котором она определена. То есть, ее нужно добавлять в .h файлы (те, которые подключаются с помощью #include) в самый верх. Она "эквивалентна" следующей, довольно популярной конструкции #ifndef _GUARD_H_ #define _GUARD_H_ //код #endif А вот проблема наблюдается потому, что Ваш h файл попадает в много разных cpp файлов. И естественно, линковщик обнаруживает много одинаковых функций и ругается. Лечиться это так. Либо просто добавьте inline к определению функции в самое начало (но это некрасиво, особенно, если функции не маленькие), либо создайте отдельный cpp файл, вынесите туда тело каждой функции, а в h файле оставьте только прототипы. Это правильный, хороший способ. Но если Ваши функции в h файле занимают по одной-две строки, то можно и через inline.

Ответ 2



Насколько я помню, она распространяется на текущий файл, т.е. должна находиться в заголовочном файле, а не вне его. Так что размещайте ее во всех своих подключаемых файлах... К Update Ваша проблема связана с тем, что объявлений допускается много, а вот определение - только одно. Видимо, вы размещаете в заголовочном файле определение функции, и в результате в каждом объектном файле имеется соответствующий код. И компоновщик не в состоянии понять, что же ему выбрать. Размещайте в заголовочных файлах только объявления. Функцию - без тела, с телом - только шаблонные и inline (можно еще static или в анонимном пространстве имен, но это даст не то, что вы на самом деле хотите - функции просто будут дублированы), переменные - только extern.

Комментариев нет:

Отправить комментарий