知识不是单独的,一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏:Visual Studio。
问题
复制一下错误信息,方便别人在检索时能检索到我这个文章。错误信息如下:
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK2005 “class NatNetClient * g_pClient” (?g_pClient@@3PEAVNatNetClient@@EA) 已经在 SampleClient.obj 中定义 GUISample C:\Users\jicha\source\repos\GUISample\GUISample.obj 1
错误截图如下:
解决方案
出现这种情况的原因有很多,有可能是:
- 当前解决方案或者工程文件里,出现了超过一个的 main() 函数,即两个程序入口
- 重复定义全局变量
- 使用第三方的库造成库之间的冲突
- 头文件的重复包含
我这里遇到的第 4 种情况,因此也就主要演示第四种的逻辑结构。
假设有三个源文件,分别是 Base.h
,Base.cpp
和 main.cpp
。
在 Base.h
里面定义一个基类,注意,基类只包含构造函数和析构函数的声明,函数在 Base.cpp
里实现。
此外在 Base.h
中还有一个函数的定义(函数声明和定义都在 Base.h
文件中)
// Base.h
#include<iostream>
#include<string>
using namespace std;
class Base{
public:
Base();
~Base();
private:
char *p;
};
void platform(Base *pBase){
cout << "this is just a function..." << endl;
}
// Base.cpp
#include "Base.h"
Base::Base(){
cout << "construction function..." << endl;
}
Base::~Base(){
cout << "destructor function..." << endl;
delete p;
}
//main.cpp
#include"Base.h"
#include<iostream>
using namespace std;
int main(){
cout << "main..." << endl;
Base * pBase = new Base;
delete pBase;
system("pause");
return 0;
}
此时如果进行编译,就会出现 LNK2005 的报错。
这是由于两个实现文件 Base.cpp
和 main.cpp
都包含了 Base.h
头文件造成的。
解决办法是:
只在头文件 Base.h
中声明函数,
函数定义都放在 Base.cpp
文件中,
具体来说也就是将 Base.h
中的 platform()
函数定义从 Base.h
中转移到 Base.cpp
中。
另外,如果在头文件中再定义一个变量,例如:int a = 10;
那么由于头文件在两个 cpp
文件中都有被包含,也会出现类似的错误。
解决办法是:
把变量的定义放到 Base.cpp
文件中。
总结:
Base.h
文件中仅放置包含头文件的 #include ""
语句和函数的声明 void fun();
;
Base.cpp
文件中放置变量的定义 int a = 10;
和函数的定义 void fun() { }
。