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 \即可。
25
让我们再编译一次。
1>test.obj : error LNK2005: \已经在 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函数:
26
static void print()。
这便告诉编译器,哥是唯一的,而且哥只能被本编译单元的代码调用,这和extern是对应的。简单来说,想要哥帮你做事,请先include哥声明的头文件,也就是#include \。
3..h头文件中只放声明,实现放到.cpp中去。
现在test.h中只有void print();,而实现在test.cpp中: #include \ void print() {
int a = 1;
cout<< a++ << endl; }
这个时候有意思的是我们在main.cpp无需包含test.h头文件也可以引用print函数,因为print并非static的函数: void print(); int main() {
print(); print(); return 0; }
但是声明一下是必须的。
由于百度空间的帖子的篇幅是有限制的,因此今天只好就说这么几点了。新的内容请大家等候下一章。 合理组织项目、使用外部工具让工作更...
27
这一章跟大家分享一些与c++项目管理、VAX、SVN、VS快捷键等方面的东西。
有效的在项目中组织C++文件,分配各种文件的目录对以后的维护会有好处的,至少不会出现不知道什么东西在什么地方,特别是大的项目,这里用TextSearcher来做例子。
使用SVN来管理项目会让我们的工作更轻松,工作也会更简单容易。 掌握常用的快捷键和常用的VS功能让我们的工作更有效。
合理的组织文件体系
首先说在IDE中为我们的文件分类组织,如下图所示:
28