LNK2005,LNK1169错误,“int __cdecl g(void)”(?g @@ YAHXZ)已定义

时间:2013-04-27 19:27:38

标签: c++ visual-c++ visual-studio-2012 linker-errors lnk2005

我在Visual Studio项目中有3个文件:test.cppdate.cppmain.cpp -

TEST.CPP:

int g() { return 0; }

date.cpp:

/*totally empty*/

main.cpp中:

#include "test.cpp"
#include "date.cpp"

int main() { return g(); }

据我所知,如果多次调用头文件,在头文件中定义函数会导致违反单一定义规则。但在这里,我只从一个文件/翻译单元调用它一次。为什么还在扔LNK2005?

3 个答案:

答案 0 :(得分:4)

您不应该包含test.cppdate.cpp。相反,您应该写test.hdate.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(); }

答案 1 :(得分:2)

由于test.cpp位于VS项目中,因此会对其进行编译并与main.cpp一起排列,从而导致多个定义 - 除非您采取特殊措施来防止这种情况发生,例如删除{{1}来自项目或将其设置为“从构建中排除”。

如果您将test.cpp重命名为temp.cpp,您将获得两项好处:

  1. VS不会在项目中自动编译test.h,因为它假定该文件旨在包含在其他文件中而不是独立编译。
  2. 程序员不会对文件的预期用途造成混淆

答案 2 :(得分:2)

您在“main.cpp”中包含“test.cpp” - 这很可能是错误的,因为Visual Studio将“test.cpp”编译为单独的文件,然后将“test.obj”链接到“ main.obj“(这些是由编译器生成的文件)到”main.exe“中。当它在“test.obj”和“main.obj”中找到“g()”时,它会说“嗯?为什么你有两个这样的”(或者,在链接器术语中是“多个定义的符号”)。

解决方案是使用“test.h”声明void g();,然后使用它包含到“main.cpp”中。