转
http://www.cnblogs.com/BlogNetSpace/archive/2009/02/12/1388943.html
http://man.chinaunix.net/develop/c&c++/c/c.htm#_Toc520634042
http://zh-google-styleguide.readthedocs.org/en/latest/google-cpp-styleguide/headers/
目录:
1、头文件的include两个格式
2、头文件的条件编译
3、头文件依赖:前置声明
4、头文件包含类容
1、头文件的include两个格式
1.1、#include <....h> 这种格式用来引用标准库的头文件,编译器默认从标准库开始搜索
1.2、#include "......h" 这种格式用来引用非标准库的头文件,编译器默认从工程当前目录开始搜索
2、头文件#define保护。即所有头文件应该使用#define进行保护,防止头文件被多重包含。就涉及到条件编译:
#ifndef, #def, #endif,#ifdef,#define
2.1、条件编译命令
#ifdef MY_HEADER_H // 如果定义了MY_HEADER_H,就编译程序段1
程序段1;
#else //否则就编译程序段2
程序段2;
#endif
#else 部分也可以没有:
#ifdef
code1;
#endif
这个也可以用在某些功能文件未实现之前和实现之后使用这个条件编译命令起到开关功能。也可以用在调试功能上。在调试阶段需要输出一些类容,不是调试阶段就不输出。当然在调试的时候定义
#define DEBUG 1 或者 #define DEBUG 0
这样在调试之前加这一句,就可以在调试的时候输出cout的内容,当不需要调试的时候,就将这个#define语句删掉,这样,就能正常执行程序的功能,不用输出调试语句,这个很方便,就不用自己去删掉或注释掉较多的输出语句。不错的功能
#ifdef DEBUG
cout<<"the debug phase"<<endl;
#endif
2.2、另外一种跟1比较相似,但是是反着的。
#ifndef DEBUG
code1;
#else
code2;
#endif
解释:相对ifdef来说,中间多了一个n,表示没有。就是如果没有定义DEBUG,编译code1,否则编译coude2
#ifndef MY_HEADER_H
#define MY_HEADER_H
.....
....
....
...
...
#endif
这个是为了防止MY_HEADER_H被重复包含。所有头文件都应该使用 #define 防止头文件被多重包含
2.3、另外一种形式,也可以用到code里面,就是code里面嵌入这个条件编译,这样就不用编译全部:
#if 表达式
code1;
#else
code2;
#endif
表示如果表达式为真,就编译code1,否则编译code2.
3 头文件依赖
对于头文件依赖,能用前置声明的尽量不使用#include。又涉及到了前置声明
3.1 前置声明(前向声明):
class Screen;
在程序中引入类类型,在声明之后,定义之前,类是一个不完全类型,即知道该类是一个类型,但是并不知道包含哪些成员。只能以有限的方式使用。只要类名一出现,就认为该类已经声明。
class B; class A{ public: B *b; }; class B{ public: ....; ....; };
对于B来说,就是一个前置声明,A要用到B,但是B不在A之前定义,A要使用B就要先声明B。
- 不完全类型不能定义该类型的对象
- 只能用于定义该类型的指针或者引用
- 或者用于声明(不是定义)使用该类型作为行参类型或返回类型的函数
- 在使用类的对象之前,一定要定义该类。这样,编译器就会给该类预定相应的存储空间。
- 在使用引用或者指针访问类的成员之前,必须定义类
转
http://blog.csdn.net/raodotcong/article/details/6431502
http://patmusing.blog.163.com/blog/static/135834960201038113714199/
第一个博客里面写的是:类h文件引用其他文件的类的时候,可以不用引入头文件,直接先声明需要引用的类名,而是在类实现文件里面引用其他类的h文件。这样就避免了一个头文件包含了其他的头文件,减少了这个文件对其他头文件的依赖。因为如果一个头文件改变,就会导致所有包含这个头文件的代码被重新编译。所以尽量在头文件少包含其他的头文件,可以选择在cpp文件里面包含其他的头文件,因为在cpp文件里面需要引用到其他类定义的成员,这个时候就必须先进行引用其他类的头文件。只是在实现文件cpp文件里面包含其他的头文件是比较好的编程风格。
包含:如果你的类是其他类的子类, 或者含有类型为其他类的非静态数据成员(对象), 则必须包含其他类所在的头文件.
4、头文件包含类容
头文件一般包含类的声明,extern变量的声明和函数的声明。
定义只有一次,声明可以多次。
4.1 头文件用于声明,而不是用于定义
extern int ival = 10;//初始化,为定义
double fica;//没有extern,也是一个定义
没有extern,同一个程序中两个以上文件含有上述任一个定义都会链接错误。
因为头文件包含在多个源文件,所以不应该含有变量或函数的定义。
较好的:extern double fical;
头文件可以包含:定义类,值在编译的时候就知道value的const对象,inline函数。
4.2 一些const对象定义在头文件中
如果const变量是由常量表达式初始化,就定义在头文件,如果不是,就不要放头文件,同时在之前加上extern以便其他文件共享。
4.3 头文件中可以包括:用户构造的数据类型(如枚举类型),外部变量,外部函数、常量和内联函数等具有一定通用性或常用的量。
而一般性的变量和函数定义不宜放在头文件中。
(下面的图片时转的:http://blog.sina.com.cn/s/blog_6db80bb101013ute.html)
转:http://www.weixueyuan.net/view/5834.html
总结:(C++primer:c++是一种静态类型语言:变量和函数在使用前必须先声明。变量可以声明多次但是只能定义一次)
转的总结:http://zh-google-styleguide.readthedocs.org/en/latest/google-cpp-styleguide/headers/
- 避免多重包含是学编程时最基本的要求;
- 前置声明是为了降低编译依赖,防止修改一个头文件引发多米诺效应;
- 内联函数的合理使用可提高代码执行效率;
- -inl.h 可提高代码可读性 (一般用不到吧:D);
- 标准化函数参数顺序可以提高可读性和易维护性 (对函数参数的堆栈空间有轻微影响, 我以前大多是相同类型放在一起);
- 包含文件的名称使用 . 和 .. 虽然方便却易混乱, 使用比较完整的项目路径看上去很清晰, 很条理, 包含文件的次序除了美观之外, 最重要的是可以减少隐藏依赖, 使每个头文件在 “最需要编译” (对应源文件处 :D) 的地方编译, 有人提出库文件放在最后, 这样出错先是项目内的文件, 头文件都放在对应源文件的最前面, 这一点足以保证内部错误的及时发现了。
下面时以后要归纳的一些东西,一一写下来:
const专题,static, extern专题,class和struct区别专题,指针专题,读写文件专题,string专题,虚函数专题(涉及到重载,覆盖(相当于重写)),内联函数专题, this指针, 析构函数,复制函数,赋值函数,初始化问题,设计模式