头文件c/c++独特的概念。

首先解释声明和定义的区别。

extern int x;这是一个可变x声明,void fun();这是函数fun()声明。class a;这是类a声明。

int x;变量x定义。void fun(){};则为fun()函数的定义,class a{};则为类a的定义。

头文件里存放预处理命令(#开头的命令),函数声明。类、结构体、联合定义(不能实例化对象),模板定义等。

而不应该包括变量定义。函数定义等。头文件里的内容不会去生成目标代码。不会去为变量声明或类定义分配内存空间,都仅仅是一些声明性的东西。#include在编译的预编译阶段展开用对应的头文件内容替换。

编译单元是指一个cpp文件。能够生成一个目标文件。同一个编译单元中能够有反复的声明,可是不同意反复的变量定义、函数定义、类定义。不同的编译单元能够有反复的声明和类定义(这里比較特殊,由于类定义仅仅是声明性的东西,没有实际产生目标代码,故能够放在不同的编译单元中,而在同一编译单元中不能反复定义),不同意反复的变量定义和函数定义。

为了防止在同一个编译单元中头文件反复引用导致出现类反复定义等问题,在每一个头文件定义时增加#ifndef  #define #endif的定义。

而且该条件编译指令也能够避免头文件的循引用,在程序预编译阶段,碰到#include命令即展开相应的头文件。在展开那个头文件时同理处理。

比方有三个头文件a.h b.h c.h,a.h里面有#include "b.h",b.h里面有#include "c.h", c.h里面有#include "a.h",这就会造成文件的循环依赖,此时若有个文件a.c。当中#include
"a.h"。那在a.c文件编译之前,预处理程序就会不断的把这三个头文件的内容复制过来。超过了一定的数量,就会导致“头文件数太多”的编译错误。当使用#ifndef...#define...#endif条件编译命令后,第一次展开a.h b.h c.h的时候就已经定义了宏,到了c.h中的#include "a.h"时候,遇到了#ifndef。因为这个宏在上一次展开时已经定义了,所以这部分就跳过去了。也就是每一个头文件最多仅仅在每一个源文件中面包括一次。

以下解决一个实际问题即两个类A,B中都有还有一个类的指针。即彼此互相引用。这里能够用前置声明来解决。

头文件a.h

#ifndef A_H
#define A_H
class B;
class A
{
public:
B* b;
};
#endif

头文件b.h

#ifndef B_H
#define B_H
class A;
class B
{
public:
A* a;
};
#endif

使用头文件时的两个原则:

1、假设能够不包括头文件,那就不要包括了。这时候前置声明能够解决这个问题。假设使用的不过一个类的指针,没有使用这个类的详细对象(非指针),也没有訪问到类的详细成员。那么前置声明就能够了。

由于指针这一数据类型的大小是特定的。编译器能够获知。

2、尽量在CPP文件里包括头文件,而非在头文件里。如果类A的一个成员是是一个指向类B的指针,在类A的头文件里使用了类B的前置声明并 廉价成功。那么在A的实现中我们须要訪问B的详细成员,因此须要包括头文件。那么我们应该在类A的实现部分(CPP文件)包括类B的头文件而不是声明节

版权声明:本文博客原创文章,博客,未经同意,不得转载。

最新文章

  1. [LeetCode] Ones and Zeroes 一和零
  2. 为C#自定义控件添加自定义事件
  3. uva-439
  4. mvc路由注意事项
  5. iOS:一些常用的框架
  6. 20145225《Java程序设计》 第5周学习总结
  7. 第二篇 :微信公众平台开发实战Java版之开启开发者模式,接入微信公众平台开发
  8. C#实现Comparable接口实现排序
  9. Java事务处理总结
  10. 《BackboneJS框架的技巧及模式》(2)
  11. 算法导论(第三版)Exercises2.1(插入排序、线性查找、N位大数相加)
  12. Swift LeetCode 目录 | Catalog
  13. java 面试题整理(不定期更新)
  14. 获取当前泛型类的传入,BaseDaoImpl<T> implements BaseDao<T>
  15. Java中的访问权限控制
  16. 2018ACM-ICPC焦作区域赛【反思总结】
  17. [No000018B]写代码要用 Vim,因为越难入门的工具回报越大
  18. Keepalived 进程无法关闭
  19. javascript单线程那些事
  20. Eclipse创建Spring项目 未完

热门文章

  1. 零基Android手机嵌入式开发培训课程
  2. 【iOS】苹果,百度Map定位使用与总结
  3. 启动和关闭JBoss As 7.1.1脚本
  4. 分享3一个博客HTML5模板
  5. 使用AndroidFrameworks开发和应用隐藏类 or Android使用自定义framework开发与应用
  6. If you pay peanuts,you get monkeys
  7. coding.net解决github上下载速度慢问题
  8. dsbskrhkme看么哦么
  9. SVNKIT一段代码的分析
  10. Jetty 9.3庆祝20周年生日快乐,并添加HTTP/2支持