C++中头文件定义及概念

已有人阅读此文 - - admin

C++中头文件定义及概念知识,C++中头文件定义及概念图片 C++中头文件定义及概念内容,C++中头文件定义及概念介绍,C++中头文件定义及概念,C++,中头,文件,定义,及,概念,一般,在,一个,的正文:

C++中头文件定义及概念包含:集成了各种键盘命令和功能。 (Gerald Weinberg) 移动到C++或许多其他编程语言中的一种。 (奥斯特霍特) 在编程时要牢记这一想法:就像将来要维护你的代码的人是一个知道你住在哪里的残忍的疯子。 软件通常在beta测试完成后不久发布。 将这些库集成到ruby on rails框架中,以扩展代码的功能。 这些允许更快和更清晰的编码。 用代码行来评估软件开发的进度就像用权重来评估飞机建造的进度一样。 当你完成了JavaSE和JavaEE的学习后, 如果一切都好,你就失业了。 红色括号给出了一个基本示例,表示另一个括号必须在附近。 你写的任何超过六个月没读过的代码,就像你再看别人的代码一样。 bootstrap是一个前端框架 PoT是一个熟悉的概念,所以很容易理解。 你越早落后,你就必须赶上更多的时间。 (马丁·戈尔丁) 可以申请发布内容 有三种:懒惰、易怒和傲慢。 绝对有必要做正确的事情。 C++中头文件定义及概念介绍的方法与命令流程等可以帮助到读者。

C++中头文件定义及概念例图

一般在一个应用开发体系中,功能的真正逻辑实现是以硬件层为基础,在驱动程序、功能层程序以及用户的应用程序中完成的。
头文件的主要作用在于多个代码文件全局变量(函数)的重用、防止定义的冲突,对各个被调用函数给出一个描述,其本身不需要包含程序的逻辑实现代码,它只起描述性作用,用户程序只需要按照头文件中的接口声明来调用相关函数或变量,链接器会从库中寻找相应的实际定义代码。 
从以上结构图来看,头文件是用户应用程序和函数库之间的桥梁和纽带。在整个软件中,头文件不是最重要的部分,但它是C语言家族中不可缺少的组成部分。编译时,编译器通过头文件找到对应的函数库,进而把已引用函数的实际内容导出来代替原有函数。进而在硬件层面实现功能。
什么样的内容适合放在头文件里?
对于具有外部存储类型的标识符,可以在其他任何一个源程序文件中经声明后引用,因此用户完全可以将一些具有外部存储类型的标识符的声明放在一个头文件中。具体地说,头文件中可以包括:用户构造的数据类型(如枚举类型),外部变量,外部函数、常量和内联函数等具有一定通用性或常用的量。而一般性的变量和函数定义不宜放在头文件中。
例如:#include<stdio.h>中的头文件stdio.h作用是让链接器通过头文件里的函数声明找到函数实际代码所在的位置即所在的库文件,这样才能使用该函数的实际代码,函数的实际代码的实现过程是先让链接器通过头文件里函数的申明找到函数实际代码所在的位置即所在的库文件,再通过#include语句把链接器所找到的函数实际代码用链接器把函数的实际代码链接到当前文件即所要执行的程序中。
当然有些函数的使用不需要提供头文件,但是在ISO/ANSI C已经对有些函数的使用必须提供哪些头文件制定了标准。
https://baike.baidu.com/item/%E5%A4%B4%E6%96%87%E4%BB%B6/10978258?fr=aladdin

一、C++编译模式

通常,在一个C++程序中,只包含两类文件——.cpp文件和.h文件。其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码;而.h文件则被称作C++头文件,里面放的也是C++的源代码。

C++语言支持“分别编译”(separate compilation)。也就是说,一个程序所有的内容,可以分成不同的部分分别放在不同的.cpp文件里。.cpp文件里的东西都是相对独立的,在编 译(compile)时不需要与其他文件互通,只需要在编译成目标文件后再与其他的目标文件做一次链接(link)就行了。比如,在文件a.cpp中定义 了一个全局函数“void a() {}”,而在文件b.cpp中需要调用这个函数。即使这样,文件a.cpp和文件b.cpp并不需要相互知道对方的存在,而是可以分别地对它们进行编译, 编译成目标文件之后再链接,整个程序就可以运行了。

这是怎么实现的呢?从写程序的角度来讲,很简单。在文件b.cpp中,在调用 “void a()”函数之前,先声明一下这个函数“void a();”,就可以了。这是因为编译器在编译b.cpp的时候会生成一个符号表(symbol table),像“void a()”这样的看不到定义的符号,就会被存放在这个表中。再进行链接的时候,编译器就会在别的目标文件中去寻找这个符号的定义。一旦找到了,程序也就可以 顺利地生成了。

注意这里提到了两个概念,一个是“定义”,一个是“声明”。简单地说,“定义”就是把一个符号完完整整地描述出来:它是变 量还是函数,返回什么类型,需要什么参数等等。而“声明”则只是声明这个符号的存在,即告诉编译器,这个符号是在其他文件中定义的,我这里先用着,你链接 的时候再到别的地方去找找看它到底是什么吧。定义的时候要按C++语法完整地定义一个符号(变量或者函数),而声明的时候就只需要写出这个符号的原型了。 需要注意的是,一个符号,在整个程序中可以被声明多次,但却要且仅要被定义一次。试想,如果一个符号出现了两种不同的定义,编译器该听谁的?

二、什么是头文件

上述机制给C++程序员们带来了很多好处,同时也引出了一种编写程序的方法。考虑一下,如果有一个很常用的函数“void f() {}”,在整个程序中的许多.cpp文件中都会被调用,那么,我们就只需要在一个文件中定义这个函数,而在其他的文件中声明这个函数就可以了。一个函数还 好对付,声明起来也就一句话。但是,如果函数多了,比如是一大堆的数学函数,有好几百个,那怎么办?能保证每个程序员都可以完完全全地把所有函数的形式都 准确地记下来并写出来吗?

很显然,答案是不可能。但是有一个很简单地办法,可以帮助程序员们省去记住那么多函数原型的麻烦:我们可以把那几百个函数的声明语句全都先写好,放在一个文件里,等到程序员需要它们的时候,就把这些东西全部copy进他的源代码中。

这个方法固然可行,但还是太麻烦,而且还显得很笨拙。于是,头文件便可以发挥它的作用了。所谓的头文件,其实它的内容跟.cpp文件中的内容是一样的,都是 C++的源代码。但头文件不用被编译我们把所有的函数声明全部放进一个头文件中,当某一个.cpp源文件需要它们时,它们就可以通过一个宏命令 “#include”包含进这个.cpp文件中,从而把它们的内容合并到.cpp文件中去。当.cpp文件被编译时,这些被包含进去的.h文件的作用便发 挥了

include 是一个来自C语言的宏命令,它在编译器进行编译之前,即在预编译的时候就会起作用。#include的作用是把它后面所写的那个文件的内容,完完整整地、 一字不改地包含到当前的文件中来。值得一提的是,它本身是没有其它任何作用与副功能的,它的作用就是把每一个它出现的地方,替换成它后面所写的那个文件的 内容。简单的文本替换,别无其他。
举一个例子吧,假设所有的数学函数只有两个:f1和f2,那么我们把它们的定义放在math.cpp里:

/* math.cpp */ 
double f1() 
{ 
//do something here…. 
return; 
} 
double f2(double a) 
{ 
//do something here… 
return a * a; 
} 
/* end of math.cpp */

并把“这些”函数的声明放在一个头文件math.h中:

/* math.h */ 
double f1(); 
double f2(double); 
/* end of math.h */

在另一个文件main.cpp中,我要调用这两个函数,那么就只需要把头文件包含进来:

/* main.cpp */

include “math.h”
main() 
{ 
int number1 = f1(); 
int number2 = f2(number1); 
} 
/* end of main.cpp */

main.cpp文件中的第一句(#include “math.h”),在编译之前就会被替换成math.h文件的内容。即在编译过程将要开始的时候,main.cpp的内容已经发生了改变:

/* ~main.cpp /
double f1();
double f2(double);
main()
{
int number1 = f1();
int number2 = f2(number1);
}
/ end of ~main.cpp */

这 样,便是一个完整的程序了。需要注意的是,.h文件必须要在编译器找得到的地方(比如跟main.cpp在一个目录下)。 main.cpp和math.cpp都可以通过预编译、编译,生成main.o和math.o,然后再把这两个目标文件进行链接,程序就可以运行了。

三、头文件中应该写什么

通 过上面的讨论,我们可以了解到,头文件的作用就是被其他的.cpp包含进去的。它们本身并不参与编译,但实际上,它们的内容却在多个.cpp文件中得到了 编译。通过“定义只能有一次”的规则,我们很容易可以得出,头文件中应该只放变量和函数的声明,而不能放它们的定义。因为一个头文件的内容实际上是会被引 入到多个不同的.cpp文件中的,并且它们都会被编译。放声明当然没事,如果放了定义,那么也就相当于在多个文件中出现了对于一个符号(变量或函数)的定 义,纵然这些定义都是相同的,但对于编译器来说,这样做不合法。

所以,应该记住的一点就是,.h头文件中,只能存在变量或者函数的声明, 而不要放定义。即,只能在头文件中写形如:extern int a;和void f();的句子。这些才是声明。如果写上int a;或者void f() {}这样的句子,那么一旦这个头文件被两个或两个以上的.cpp文件包含的话,编译器会立马报错。

但是,这个规则是有三个例外的。

  1. 头文件中可以写const对象的定义。因为全局的const对象默 认是没有extern的声明的,所以它只在当前文件中有效。把这样的对象写进头文件中,即使它被包含到其他多个.cpp文件中,这个对象也都只在包含它的 那个文件中有效,对其他文件来说是不可见的,所以便不会导致多重定义。同时,因为这些.cpp文件中的该对象都是从一个头文件中包含进去的,这样也就保证 了这些.cpp文件中的这个const对象的值是相同的,可谓一举两得。同理,static对象的定义也可以放进头文件。

  2. 头文件中可 以写内联函数(inline)的定义。因为inline函数是需要编译器在遇到它的地方根据它的定义把它内联展开的,而并非是普通函数那样可以先声明再链 接的(内联函数不会链接),所以编译器就需要在编译时看到内联函数的完整定义才行。如果内联函数像普通函数一样只能定义一次的话,这事儿就难办了。因为在 一个文件中还好,我可以把内联函数的定义写在最开始,这样可以保证后面使用的时候都可以见到定义;但是,如果我在其他的文件中还使用到了这个函数那怎么办 呢?这几乎没什么太好的解决办法,因此C++规定,内联函数可以在程序中定义多次,只要内联函数在一个.cpp文件中只出现一次,并且在所有的.cpp文 件中,这个内联函数的定义是一样的,就能通过编译。那么显然,把内联函数的定义放进一个头文件中是非常明智的做法。

  3. 头文件中可以写类 (class)的定义。因为在程序中创建一个类的对象时,编译器只有在这个类的定义完全可见的情况下,才能知道这个类的对象应该如何布局,所以,关于类的 定义的要求,跟内联函数是基本一样的。所以把类的定义放进头文件,在使用到这个类的.cpp文件中去包含这个头文件,是一个很好的做法。在这里,值得一提 的是,类的定义中包含着数据成员和函数成员。数据成员是要等到具体的对象被创建时才会被定义(分配空间),但函数成员却是需要在一开始就被定义的,这也就 是我们通常所说的类的实现。一般,我们的做法是,把类的定义放在头文件中,而把函数成员的实现代码放在一个.cpp文件中。这是可以的,也是很好的办法。 不过,还有另一种办法。那就是直接把函数成员的实现代码也写进类定义里面。在C++的类中,如果函数成员在类的定义体中被定义,那么编译器会视这个函数为 内联的。因此,把函数成员的定义写进类定义体,一起放进头文件中,是合法的。注意一下,如果把函数成员的定义写在类定义的头文件中,而没有写进类定义中, 这是不合法的,因为这个函数成员此时就不是内联的了。一旦头文件被两个或两个以上的.cpp文件包含,这个函数成员就被重定义了。

五、头文件中的保护措施

如果头文件中只包含声明语句的话,它被同一个.cpp文件包含再多次都没问题——因为声明语句的出现是不受限制的。然而上面讨论到的头文件中的 三个例外也是头文件很常用的一个用处。那么,一旦一个头文件中出现了上面三个例外中的任何一个,它再被一个.cpp包含多次的话,问题就大了。因为这三个 例外中的语法元素虽然“可以定义在多个源文件中”,但是“在一个源文件中只能出现一次”。设想一下,如果a.h中含有类A的定义,b.h中含有类B的定 义,由于类B的定义依赖了类A,所以b.h中也#include了a.h。现在有一个源文件,它同时用到了类A和类B,于是程序员在这个源文件中既把 a.h包含进来了,也把b.h包含进来了。这时,问题就来了:类A的定义在这个源文件中出现了两次!于是整个程序就不能通过编译了。你也许会认为这是程序 员的失误——他应该知道b.h包含了a.h——但事实上他不应该知道。

使用”#define”配合条件编译可以很好地解决这个问题。在一 个头文件中,通过#define定义一个名字,并且通过条件编译#ifndef…#endif使得编译器可以根据这个名字是否被定义,再决定要不要继 续编译该头文中后续的内容。这个方法虽然简单,但是写头文件时一定记得写进去。
https://www.jianshu.com/p/c4fcf1b62533

C/C++常用头文件及函数汇总

 

C/C++头文件一览

C

#include <assert.h>    //设定插入点
#include <ctype.h>     //字符处理
#include <errno.h>     //定义错误码
#include <float.h>     //浮点数处理
#include <iso646.h>        //对应各种运算符的宏
#include <limits.h>    //定义各种数据类型最值的常量
#include <locale.h>    //定义本地化C函数
#include <math.h>     //定义数学函数
#include <setjmp.h>        //异常处理支持
#include <signal.h>        //信号机制支持
#include <stdarg.h>        //不定参数列表支持
#include <stddef.h>        //常用常量
#include <stdio.h>     //定义输入/输出函数
#include <stdlib.h>    //定义杂项函数及内存分配函数
#include <string.h>    //字符串处理
#include <time.h>     //定义关于时间的函数
#include <wchar.h>     //宽字符处理及输入/输出
#include <wctype.h>    //宽字符分类

传统C++

#include <fstream.h>    //改用<fstream>
#include <iomanip.h>    //改用<iomainip>
#include <iostream.h>   //改用<iostream>
#include <strstrea.h>   //该类不再支持,改用<sstream>中的stringstream

————————————————————————————————

标准C++ 

#include <algorithm>    //STL 通用算法
#include <bitset>     //STL 位集容器
#include <cctype>         //字符处理
#include <cerrno>      //定义错误码
#include <cfloat>     //浮点数处理
#include <ciso646>         //对应各种运算符的宏
#include <climits>     //定义各种数据类型最值的常量
#include <clocale>     //定义本地化函数
#include <cmath>      //定义数学函数
#include <complex>     //复数类
#include <csignal>         //信号机制支持
#include <csetjmp>         //异常处理支持
#include <cstdarg>         //不定参数列表支持
#include <cstddef>         //常用常量
#include <cstdio>      //定义输入/输出函数
#include <cstdlib>     //定义杂项函数及内存分配函数
#include <cstring>     //字符串处理
#include <ctime>      //定义关于时间的函数
#include <cwchar>      //宽字符处理及输入/输出
#include <cwctype>     //宽字符分类
#include <deque>      //STL 双端队列容器
#include <exception>    //异常处理类
#include <fstream>     //文件输入/输出
#include <functional>   //STL 定义运算函数(代替运算符)
#include <limits>      //定义各种数据类型最值常量
#include <list>      //STL 线性列表容器
#include <locale>         //本地化特定信息
#include <map>       //STL 映射容器
#include <memory>         //STL通过分配器进行的内存分配
#include<new>            //动态内存分配
#include <numeric>         //STL常用的数字操作
#include <iomanip>     //参数化输入/输出
#include <ios>       //基本输入/输出支持
#include <iosfwd>     //输入/输出系统使用的前置声明
#include <iostream>    //数据流输入/输出
#include <istream>     //基本输入流
#include <iterator>        //STL迭代器
#include <ostream>     //基本输出流
#include <queue>      //STL 队列容器
#include <set>       //STL 集合容器
#include <sstream>     //基于字符串的流
#include <stack>      //STL 堆栈容器
#include <stdexcept>    //标准异常类
#include <streambuf>    //底层输入/输出支持
#include <string>     //字符串类
#include <typeinfo>        //运行期间类型信息
#include <utility>     //STL 通用模板类
#include <valarray>        //对包含值的数组的操作
#include <vector>     //STL 动态数组容器

————————————————————————————————

C99增加的部分

#include <complex.h>   //复数处理
#include <fenv.h>    //浮点环境
#include <inttypes.h>  //整数格式转换
#include <stdbool.h>   //布尔环境
#include <stdint.h>   //整型环境
#include <tgmath.h>   //通用类型数学宏

头文件 ctype.h
字符处理函数: 本类别函数用于对单个字符进行处理,包括字符的类别测试和字符的大小写转换

字符测试是否字母和数字 isalnum
是否字母 isalpha
是否控制字符 iscntrl
是否数字 isdigit
是否可显示字符(除空格外) isgraph
是否可显示字符(包括空格) isprint
是否既不是空格,又不是字母和数字的可显示字符 ispunct
是否空格 isspace
是否大写字母 isupper
是否16进制数字(0-9,A-F)字符 isxdigit
字符大小写转换函数 转换为大写字母 toupper
转换为小写字母 tolower

头文件 local.h
地区化: 本类别的函数用于处理不同国家的语言差异。

地区控制 地区设置 setlocale
数字格式约定查询 国家的货币、日期、时间等的格式转换 localeconv


头文件 math.h
数学函数: 本分类给出了各种数学计算函数,必须提醒的是ANSIC标准中的数据格式并不符合IEEE754标准,一些C语言编译器却遵循IEEE754(例如frinklin C51)


反余弦 acos
反正弦 asin
反正切 atan
反正切2 atan2
余弦 cos
正弦 sin
正切 tan

双曲余弦 cosh
双曲正弦 sinh
双曲正切 tanh

指数函数 exp
指数分解函数 frexp
乘积指数函数 fdexp
自然对数 log
以10为底的对数 log10
浮点数分解函数 modf

幂函数 pow
平方根函数 sqrt

求下限接近整数 ceil
绝对值 fabs
求上限接近整数 floor
求余数 fmod



头文件 setjmp.h io.h
本分类函数用于实现在不同底函数之间直接跳转代码。

保存调用环境 setjmp
恢复调用环境 longjmp

头文件 signal.h
信号处理: 该分类函数用于处理那些在程序执行过程中发生例外的情况。

指定信号处理函数 signal
发送信号 raise


头文件 stdarg.h
可变参数处理: 本类函数用于实现诸如printf,scanf等参数数量可变底函数。

可变参数访问宏
可变参数开始宏 va_start
可变参数结束宏 va_end
可变参数访问宏 访问下一个可变参数宏 va_arg


头文件 stdio.h
输入输出函数:该分类用于处理包括文件、控制台等各种输入输出设备,各种函数以“流”的方式实现

删除文件 remove
修改文件名称 rename
生成临时文件名称 tmpfile
得到临时文件路径 tmpnam
文件访问 关闭文件 fclose
刷新缓冲区 fflush
打开文件 fopen
将已存在的流指针和新文件连接 freopen
设置磁盘缓冲区 setbuf
设置磁盘缓冲区 setvbuf

格式化输入与输出函数
格式输出 fprintf
格式输入 fscanf
格式输出(控制台) printf
格式输入(控制台) scanf
格式输出到缓冲区 sprintf
从缓冲区中按格式输入 sscanf
格式化输出 vfprintf
格式化输出 vprintf
格式化输出 vsprintf

字符输入输出函数
输入一个字符 fgetc
字符串输入 fgets
字符输出 fputc
字符串输出 fputs
字符输入(控制台) getc
字符输入(控制台) getchar
字符串输入(控制台) gets
字符输出(控制台) putc
字符输出(控制台) putchar
字符串输出(控制台) puts
字符输出到流的头部 ungetc

直接输入输出
直接流读操作 fread
直接流写操作 fwrite

文件定位函数
得到文件位置 fgetpos
文件位置移动 fseek
文件位置设置 fsetpos
得到文件位置 ftell
文件位置复零位 remind

错误处理函数
错误清除 clearerr
文件结尾判断 feof
文件错误检测 ferror
得到错误提示字符串 perror

头文件 stdlib.h
实用工具函数: 本分类给出了一些函数无法按以上分类,但又是编程所必须要的。

字符串转换函数
字符串转换为整数 atoi
字符串转换为长整数 atol
字符串转换为浮点数 strtod
字符串转换为长整数 strtol
字符串转换为无符号长整型 strtoul

伪随机序列产生函数
产生随机数 rand
设置随机函数的起动数值 srand

存储管理函数
分配存储器 calloc
释放存储器 free
存储器分配 malloc
重新分配存储器 realloc

环境通信
中止程序 abort
退出程序执行,并清除环境变量 atexit
退出程序执行 exit
读取环境参数 getenv
程序挂起,临时执行一个其他程序 system
搜索和排序工具 二分查找(数据必须已排序) bsearch
快速排序 qsort
整数运算函数 求绝对值 abs
得到除法运算底商和余数 div
求长整形底绝对值 labs
求长整形除法的商和余数 ldiv
多字节字符函数 得到多字节字符的字节数 mblen
得到多字节字符的字节数 mbtowc
多字节字符转换 wctomb
多字节字符的字符串操作 将多字节串转换为整数数组 mbstowcs
将多字节串转换为字符数组 mcstowbs

头文件 string.h
字符串处理: 本分类的函数用于对字符串进行合并、比较等操作

字符串拷贝 块拷贝(目的和源存储区不可重叠) memcpy
块拷贝(目的和源存储区可重叠) memmove
串拷贝 strcpy
按长度的串拷贝 strncpy
字符串连接函数 串连接 strcat
按长度连接字符串 strncat
串比较函数 块比较 memcmp
字符串比较 strcmp
字符串比较(用于非英文字符) strcoll
按长度对字符串比较 strncmp
字符串转换 strxfrm
字符与字符串查找 字符查找 memchr
字符查找 strchr
字符串查找 strcspn
字符串查找 strpbrk
字符串查找 strspn
字符串查找 strstr
字符串分解 strtok
杂类函数 字符串设置 memset
错误字符串映射 strerror
求字符串长度 strlen

头文件 time.h
日期和时间函数: 本类别给出时间和日期处理函数

时间操作函数得到处理器时间 clock
得到时间差 difftime
设置时间 mktime
得到时间 time
时间转换函数 得到以ASCII码表示的时间 asctime
得到字符串表示的时间 ctime
得到指定格式的时间 strftime

序号 库类别 头文件

1   错误处理      errno.h
2   字符处理      ctyphe.
3   地区化        local.h
4   数学函数      math.h
5   信号处理      signal.h
6   输入输出      stdio.h
7   实用工具程序   stdlib.h
8   字符串处理     string.h

https://www.cnblogs.com/zuiuren/p/6067400.html
C++ 中类的声明和类的定义分开几乎成了一个不成文的规定。这样做的好处是使得类的声明和实现分开,清晰明了,同时便于库函数发布。但是在实际编程中由此也常常 引起了一些由于头文件的包含顺序问题而产生的符号未定义的编译错误,不明白其中原理有时会让人很头疼。要消除符号未定义的错误的编译错误,最基本的一个做 法就是在引用一个符号(包括变量,函数,结构,类等)之前确保它已经声明或者已经定义。
 
    实际中编码设计过程中,最基本的一个原则就是在类的头文件中最好不要包含其他头文件,因为这样会使类之间的文件包含关系变得复杂化。要最大限度的遵守这个原则,实际编码设计过程可以采用以下两种方法:
 
    方法一是在设计一个类的时候尽量保持类的独立性,即使该类尽可能不要依赖其他类库或者函数库,或者退一步来说,尽量不要在类的声明中依赖其他类。这样,在 该类的声明头文件中就可以没有其他头文件。如果实现中用到了其他的类,那么可以只在该类的实现文件中包含用到的类库或者函数库的头文件就行。
 
    方法二是当类的声明中必须得用到其他类库或者函数库时,方法一便不再适用,当一个类声明中引用的是其他类或结构的指针引用或者是函数引用时,也可以保持上 述原则,做法是采用前向引用,及在该类的声明前面先声明一下该类所用到的类名或者函数名就行。当类声明中引用的是其他类的实例时,上述原则变不能保持,只 有在该类的声明头文件中引用所引用的类库或者函数库的头文件。
然而,实际中,如果一个类要用到很多其他的类指针或者结构指针或者函数名时,虽然采用上述方法二可以保持上述原则,但是在该类的前面将所有用到的类和方法声明一遍会比较麻烦,这种情况下,为了方便也只好在该类的声明头文件中加入其他类库或者函数库中的头文件了。
 
下面举几个例子:
例子1:最简单的一种情况:两个类A和B之间完全没有关系
这种情况下两个类的声明和定义文件中根本不需要包含对方的声明头文件。(虽然是废话,但是很多人的代码中却大量存在这种情况下仍然互相包含或者包含头文件的情况,主要原因:懒,不想多思考)
 
例子2:两个类A和B在实现的时候用到了对方
这种情况只需要在每个类的实现文件文件中包含所用到的类的头文件即可。
 
例子3:两个类A和B在声明的时候通过指针引用到了对方
这种情况下可以在类的声明(头文件中)前面声明一下所用到的类,然后在各自的头文件中包含所用的类的声明头文件。比如:
// A.h
class   B;   
class   A   
{   
B   *pb;   
}
 
// B.h  
class   A;   
class   B   
{   
A   *pa;   
}
 
// A.cpp
#inclue "B.h"
#inclue "A.H"
......
 
// B.cpp
#inclue "A.h"
#inclue "B.h"
......
 
    还有,在大型工程程序设计中,一个类往往需要用到很多已有的类库及函数库,把一个类所用到的所有类库头文件都加入到类的定义头文件中往往也非常麻烦,这时 的做法是把那些经常用到的头文件加入到一个公共的头文件中,这个公共头文件在比如叫push.h。要注意的是一些头文件也有依赖关 系,这些文件的包含顺序也小心,否则就会出错。ps,头文件的包含顺序应该是从最特殊到一般,比如:我们应该以这样的方式来#include头文件:
从最特殊到最一般,也就是,
#include "本类头文件"
#include "本目录头文件"
#include "自己写的工具头文件"
#include "第三方头文件"
#include "平台相关头文件"
#include "C++库头文件"
#include "C库头文件"
http://blog.chinaunix.net/uid-20554957-id-5781352.html

1C++中头文件定义及概念系部分转载自网络,如有对程序员或作者侵犯,请联系我们立即删除,另:本文仅代表作者个人观点,与本网站无关。

2C++中头文件定义及概念这篇文章的原创性以及文中对于编程运维专业度的陈述文字 和内容未经本站证实,对本文以及其中全部或者部分内容及图片的有效性、文字的真实性、完整性、及时性本站不作任何保证或承诺以及推荐,本站非盈利,有对图片文字不适的请程序员及读者仅作参考并自行核实相关内容

3这篇C++中头文件定义及概念的文章,涉及的C++,中头,文件,定义,及,概念,一般,在,一个,命令,变量,函数,代码,类,库等皆是代称