多了说多了,如果你觉得复杂可以暂时跳过这些东西,我只是顺便说 说。
重定义的编译错误和链接错误
让我们在项目里面再添加一个 Test.h 头文件, 方法是右击解决
方案中的项 目,添加,新建项,C++头文件,名称输入 test.h。然后我们在 test.h 中输入: /*#pragma once*/
void print() { } 回到 main.cpp 中: #include
using namespace std; #include "Test.h" #include "Test.h" int main() { return 0; } 编译一下我们会得到重定义的编译错误: error C2084: 函数“void print(void)”已有主体 或许你会说,你引用(#include)了两次,我没你那么傻,我只引用一次不 就好了么?是的。你聪明,但是是小聪明哈,因
为你不能保证每个人都不去引用 它。 这个问题演示的是#pragma once 的用处,让我们解开它的注释。编译成功! #pragma once 的作用就在于防止头文件被多次引用。你或许见过 #ifndef __TEST_H__ #define__TEST_H__ 代码 #endif 这样的代码,它们的作用是一样的,如果你跟我一样懒,那么就用#pragma once,如果你打算去没有这个指令的编译器上编译代码,那么还是用后面一种方 式吧。 现在让我们来见识一个对初学者稍微复杂一点的链接错误,用创建 main.cpp 的方法再添加一个 test.h 头文件,输入#include "Test.h"即可。
让我们再编译一次。 1>test.obj : error LNK2005: "void __cdecl print(void)" (?print@@YAXXZ) 已经在 Main.obj 中定义 1>e:\documents\visual studio 2010\Projects\HelloWorld\Debug\HelloWorld.exe : fatal error LNK1169: 找 到一个或多个多重定义的符号 如果说编译错误好找的话,链接错误对于初学者来说就有点麻烦了,聪 明的初学者会去 Google、百度寻找答案,笨的初学者就会找所谓的高手、前辈 问,而这些高手 Or 前辈未必有心情为你解释。要解决这个错误有无数种方法。 1.内联,把 print 声明为内联函数。 inline void print() { } 这个方法的好处是简单,坏处是局限性太强,意味着你总是需要公开 print 的实现,因为内联函数必须在编译时就知道实现才行。 2.static,把 print 声明为 static 函数: static void print()。 这便告诉编译器,哥是唯一的,而且哥只能被本编译单元的代码调用, 这和 extern 是对应的。简单来说,想要哥帮你做事,请先 include 哥声明的头 文件,也就是#include "test.h"。
3..h 头文件中只放声明,实现放到.cpp 中去。 现在 test.h 中只有 void print();,而实现在 test.cpp 中: #include "Test.h" void print() { int a = 1; cout<< a++ << endl; } 这个时候有意思的是我们在 main.cpp 无需包含 test.h 头文件也可以 引用 print 函数,因为 print 并非 static 的函数: void print(); int main() { print(); print(); return 0; } 但是声明一下是必须的。 由于百度空间的帖子的篇幅是有限制的, 因此今天只好就说这么几点了。 新的内容请大家等候下一章。