如 lonmaor 所说。防止头文件被重复包含一般是用条件预处理命令:
程序代码:
#ifndef XXX
#define XXX
/* content of this header */
#endif
这样第一次包含这个文件的时候,由于 XXX 没有其它文件定义,因而 if 和 endif 之间的内容会被执行,从而定义了 XXX,和头文件中本来需要定义的东西。
之后如果再包含这个头文件,由于 XXX 已经定义过了。会跳过 if 和 endif 之间的内容。相当于什么都没干。
但这依然不是万能的解决方法。因为如果一个变量既在 a.h 中有所定义,又在 b.h 中有所定义。那么最终会因为重复定义而产生错误。
所以一般只能用 exterm 声明变量,而在对应的 cpp 中定义。因为 cpp 不会被其它文件包含,从而保证变量最多被定义一次。
但使用这种技术不表代就不会出问题。比如如果设计不当,就可能会出现循环包含。比如 a.h 包含 b.h,而 b.h 又包含 a.h。这种情况也许比较少见,但工程复杂之后间接的循环包含却可能会出现。设计良好的头文件不应该出现任何循环包含。
你 b 问的那个问题,contents 其实只是类 screen 定义的一部分。并不是在单独定义变量,因此不用加 extern。而在 cpp 里,也只用包含这个头文件就可以了。不用再重新定义。
按道理来讲,类和变量一样,不应该定义在 .h 里。但实际上人们却不是这么做的。
对于一个变量来说,知道它的类型,编译器就等于知道了它的一切。但是对于类来说,编译器如果见不到它的完整定义,根本无法确定它的有关信息。比如应该为它分配几个字节的内存,或者它有哪些成员函数等等。
所以类必须得定义在头文件里,包含之后才能使用。不过这样的话 a.h 和 b.h 里都定义了同名的类,那就会出错。名空间的一个目的就是为了减少这种情况带来的冲突,但需要精心的设计。这和刚才说头文件的设计一样,问题没有万能的解决方法。
2.又有一章说:类定义放在.h里,成员函数定义一般放在同名的源文件里 a. 结合问题1,变量声明在头文件,这说函数定义在源文件。那变量定义在哪?
变量应该定义在 cpp 里。原因如上述。
b. 我们写main时包含了头文件,但没提 其同名源文件的事啊,编译器会自动去找?
只要编译能获得类型相关的全部信息,它就可以完成编译的工作。比如编译器只要知道 int func(int, int) 这个函数原型,就能正确处理传参数、正确处理返回值的问题。并生成正确的函数调用的代码。而不需要知道函数的定义。
比如你包含的系统库中的函数,有些就只有函数原型,没有定义。但这不影响编译的过程。
所有源文件都编译完成之后,还有链接的的工作。它负责把函数调用和函数的定义联系在一起。它会在一些指定的地方查找函数的定义,比如系统库文件的位置和当前工程指定的位置。如果这时链接器发现有该找的函数定义找不到,就会产生链接错误。这一般和语法错误有明显区别。
头文件和源文件同不同名,其实对于编译和链接来说都无关紧要。一个头文件中声明的函数,即使定义在数个源文件里也是可以的。但是人喜欢看同名的。因为之后找起来方便,逻辑关系也更清楚些。
c. 我用vs2010 的添加选项:除了创建项里有头文件,还有一个创建类。那用这个创建类的选项和 书上所说,用头文件,源文件的方式有区别吗?有的话哪个好?
自动创建和手动创建没有本质区别。但前者由于自动化,可以节约一些时间和精力。至于哪个好,是个人品味的问题。如果用得习惯,当然是自动化的方法好喽。
d. 创建的头文件不在当前的工程下,要包含这个头文件仍是直接#include"screen"就好了?
如果可以搜索得到,包含一下就行了。如果不能,讲按 2楼 讲的方法进行设置。
有些问题讲得稍微深了点。楼主尽量理解就好。
[
本帖最后由 pangding 于 2012-8-22 22:09 编辑 ]