У меня есть 3 файла в проекте Visual Studio: test.cpp
, date.cpp
а также main.cpp
—
test.cpp:
int g() { return 0; }
date.cpp:
/*totally empty*/
main.cpp:
#include "test.cpp"#include "date.cpp"
int main() { return g(); }
Я понимаю, что определение функций в заголовочном файле приводит к нарушению правила One-Definition, если заголовочный файл вызывается несколько раз. Но здесь я звоню только один раз из одного файла / переводчика. Почему до сих пор выбрасывает LNK2005?
Вы включаете «test.cpp» в «main.cpp» — это, скорее всего, неправильно, поскольку Visual Studio ТАКЖЕ скомпилирует «test.cpp» в виде отдельного файла, а затем свяжет «test.obj» с «main.obj». msgstr «(это файлы, сгенерированные компилятором) в» main.exe «. Когда он находит «g ()» в обоих «test.obj» и «main.obj», он говорит: «А? Почему у вас есть два из них» (или, в терминах компоновщика, «несколько определенных символов»).
Решение состоит в том, чтобы иметь «test.h», который объявил void g();
и затем использовать это для включения в «main.cpp».
Вы не должны включать test.cpp
а также date.cpp
, Вместо этого вы должны написать test.h
а также date.h
и включите его:
test.h
int g();
date.h
// Contains prototypes for functions inside date.cpp
main.cpp
#include "test.h"#include "date.h"
int main() { return g(); }
поскольку test.cpp
находится в проекте VS, он будет скомпилирован и выровнен вместе с main.cpp
вызывая множественные определения — если вы не примете особые меры, чтобы предотвратить это, как удаление test.cpp
из проекта или установив его как «Исключен из сборки».
Если вы переименуете temp.cpp
в test.h
Вы получаете два преимущества:
.h
когда он находится в проекте, так как предполагается, что файл предназначен для включения из других файлов, а не для автономной компиляции.