链接器的工作:链接所有的obj文件到一个程序。
一个常见的链接错误: fatal error LNK1169: 找到一个或多个多重定义的符号。
这个错误是链接器在查找符号的过程中找到两个或以上的相同符号,链接器不知道应该链接到哪个。
例如:
//test.h
int sum(int a, int b)
{
return a + b;
}
//test.cpp
#include "test.h"
void MySum()
{
int x = sum(2, 3);
}
//demo.cpp
#include "test.h"
int main()
{
sum(1, 2);
return 0;
}
编译后会报错。
因为每个cpp文件都是一个编译单元。编译器在编译的时候只针对当前cpp文件,因为两个cpp文件都include"test.h"。所以相当于
//test.cpp
int sum(int a, int b)
{
return a + b;
}
void MySum()
{
int x = sum(2, 3);
}
//demo.cpp
int sum(int a, int b)
{
return a + b;
}
int main()
{
sum(1, 2);
return 0;
}
看到了吗,sum函数出现了两次,编译器编译了两个相同的函数,生成了两个相同的符号。
如何解决:
1.static关键字
//test.h
//static意味着该函数链接时,只在该文件内部
static int sum(int a, int b)
{
return a + b;
}
2.inline关键字
//test.h
//inline直接使用函数体
inline int sum(int a, int b)
{
return a + b;
}
3.声明与实现分开写
//test.h
int sum(int a, int b);
//test.cpp
#include "test.h"
int sum(int a, int b)
{
return a + b;
}
void MySum()
{
int x = sum(2, 3);
}
总结
理解编译和链接的过程,不要重复定义符号。