一、注意编译和运行整个文件的区别
例如:源文件中编写了Log文件的代码,生成两个数相乘的值
而声明并在main函数中调用了一个Logr文件,则使用编译器编译当前文件(Ctrl+F7),无错误。
但是运行整个文件(F5),链接器会发现无法编译。
实际上就是链接器在整个解决方案中无法将main函数中的Logr的代码展开,导致了错误。
PS:上述linking发生在main函数中,实际上如果在其他函数中互相调用了,即使main函数无需展开,但是运行整个文件也会出错。例如仍然有一个Logr函数写入Log文件,但是并未调用于main函数中,而是出现在Multiply函数,编译无错误但是运行整个文件有错。
这是因为无法保证Multiply函数不被其他文件所调用(Linking会检查全局)。
所以解决方案是:将Multiply函数加上static即可,保证只在该文件内部有效,而不会与其他文件交叉,其他.obj文件不可见(作用域变小)。
二、不能让函数在多个文件中里定义,不然就会出现重复定义的情况,导致错误。
例如:首先在一个Log.h的头文件中定义了Log函数
在Log.cpp和ConsoleApplication.cpp中分别声明了 #include "Log.h"
此时编译无错,运行失败,因为#include相当于直接把Log函数定义直接带入两个文件中,多次声明了Log函数的定义,所以解决方案是:
解决方案:
1.在Log.h头文件中使用static,让Log的定义仅在当前文件有效。
2.在Log.h头文件中使用inline(内联):直接将函数的身体拿过来取代调用,而不会先定义、后调用。
3.只在一个函数中定义,而其他函数中只声明。
Ps:一般我们可以将声明(如 void Log(const char *message) 和 void Init() )放在同一个头文件#include "Log.h"(也即预处理指令文件)中,再用Log.cpp进行定义所有函数,最后在ConsoleApplication.cpp中利用头文件进行声明即可,这样可以保证函数只在某一个文件中被定义,即每个源代码的作用清晰明了,分类检查也不会出错。