06头文件Word文档格式.docx
《06头文件Word文档格式.docx》由会员分享,可在线阅读,更多相关《06头文件Word文档格式.docx(6页珍藏版)》请在冰点文库上搜索。
![06头文件Word文档格式.docx](https://file1.bingdoc.com/fileroot1/2023-5/10/2a65c5da-f2b9-44c4-a6d1-bed916fd0d11/2a65c5da-f2b9-44c4-a6d1-bed916fd0d111.gif)
头文件由三部分内容组成:
(1)头文件开头处的版权和版本声明(参见示例1-1)。
(2)预处理块。
(3)函数和类结构声明等。
假设头文件名称为graphics.h,头文件的结构参见示例1-2。
【规则1-2-1】为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块。
【规则1-2-2】用#include<
filename.h>
格式来引用标准库的头文件(编译器将从标准库目录开始搜索)。
【规则1-2-3】用#include“filename.h”格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)。
【建议1-2-1】头文件中只存放“声明”而不存放“定义”
在C++语法中,类的成员函数可以在声明的同时被定义,并且自动成为内联函数。
这虽然会带来书写上的方便,但却造成了风格不一致,弊大于利。
建议将成员函数的定义与声明分开,不论该函数体有多么小。
【建议1-2-2】不提倡使用全局变量,尽量不要在头文件中出现象externintvalue这类声明。
//版权和版本声明见示例1-1,此处省略。
#ifndefGRAPHICS_H//防止graphics.h被重复引用
#defineGRAPHICS_H
#include<
math.h>
//引用标准库的头文件
…
#include“myheader.h”//引用非标准库的头文件
voidFunction1(…);
//全局函数声明
classBox//类结构声明
{
…
};
#endif
示例1-2C++/C头文件的结构
1.3定义文件的结构
定义文件有三部分内容:
(1)定义文件开头处的版权和版本声明(参见示例1-1)。
(2)对一些头文件的引用。
(3)程序的实现体(包括数据和代码)。
假设定义文件的名称为graphics.cpp,定义文件的结构参见示例1-3。
#include“graphics.h”//引用头文件
//全局函数的实现体
voidFunction1(…)
}
//类成员函数的实现体
voidBox:
:
Draw(…)
示例1-3C++/C定义文件的结构
1.4头文件的作用
早期的编程语言如Basic、Fortran没有头文件的概念,C++/C语言的初学者虽然会用使用头文件,但常常不明其理。
这里对头文件
的作用略作解释:
(1)通过头文件来调用库功能。
在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。
用
户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。
编译器会从库中提取相应的代码。
(2)头文件能加强类型安全检查。
如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这
一简单的规则能大大减轻程序员调试、改错的负担。
一般来说,头文件提供接口,源文件提供实现。
但是有些实现比较简单的,也可以直接写在头文件里,这样头文件接口实现一起提供。
在编译时,源文件里的实现会被编译成临时文件,运行时刻程序找到头文件里的接口,根据接口找到这些临时文件,来调用它们这些实现。
之所以在C++中要使用头文件,最主要的原因是C++的同一个项目可能有多个源代码文件,要命的是这些源代码是分别单独编译的。
也就是说,在编译其中一个文件时,编译器并不知道其它文件中定义的内容,如类、全局变量等。
这就要求我们必须在要使用某个类、函数或变量的每个文件中声明它,否则C++是无法找到它的。
很多文件可能都需要使用加法。
假设有一个文件b.cpp需要使用这个函数,那么,它必须先声明它,虽然不需要再重写。
如果有很多文件都要使用这个函数,那么这会变得麻烦,特别的,如果你写了一个类,那么你需要维护大量的声明(对于每一个public对象),并且如果你的类的定义发生了改变,你可能不得不改变无数个声明。
所以,C++语言提出了头文件的概念。
你只需要在头文件中声明一次,在实现文件中定义一次,在所有需要用的文件中,就只需要引用这个头文件,相当于每个文件都包含了一个声明。
为了防止头文件的重复包含,通常应该使用预处理指令#define(定义符号)、#ifndef(如果没有定义)、#endif(结束判断)来书写头文件的内容。
请理解如下的例子,它是对上个笔记中的Xiao类的改进。
如同名字一样的意思,NameSpace:
名字空间,之所以出来这样一个东西,是因为人类可用的单词数太少,并且不同的人写的程序不可能所有的变量都没有重名现象,对于库来说,这个问题尤其严重,如果两个人写的库文件中出现同名的变量或函数(不可避免),使用起来就有问题了,为了解决这个问题,引入了名字空间这个概念,通过使用usingnamespacexxx;
你所使用的库函数或变量就是在该名字空间中定义的.这样以来就不会引起不必要的冲突了.
所谓namespace,是指标识符的各种可见范围。
C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
一:
<
iostream>
和<
iostream.h>
格式不一样,前者没有后缀,实际上,在你的编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。
后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。
因此,当使用<
时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;
当使用<
的时候,该头文件没有定义全局命名空间,必须使用namespacestd;
这样才能正确使用cout。
因为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。
所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都被放在名字空间std中。
但这又会带来了一个新问题。
无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。
usingnamespacestd;
是定义全局空间。
c++中的头文件#include<
等引用时必须加usingnamespacestd;
不加的话,需要有std:
cout这样的形式来引用库中的内容。
而C中的则不必如#include<
string.h>
和#include<
cstring>
效果相同。
名字空间,实质上也是为了方便程序在不同平台上正确的运行。
namespace是为了解决C++中的名字冲突而引入的。
什么是名字冲突呢?
比如,在文件x.h中有个类MyClass,在文件y.h中也有个类MyClass,而在文件z.cpp中要同时引用x.h和y.h文件。
显然,按通常的方法是行不能的,那怎么办呢?
引入namespace即可。
例如:
在x.h中的内容为
//x.h
namespaceMyNamespace1
{
classMyClass
{
public:
voidf();
private:
intm;
}
};
在y.h中的内容为
//y.h
namespaceMyNamespace2
然后在z.cpp中引入x.h和y.h
//z.cpp
#include"
x.h"
y.h"
voidz:
f()
//声明一个文件x.h中类MyClass的实例x
MyNamespace1:
MyClassx;
MyNamespace2:
MyClassy;
//调用文件x.h中的函数f
x.f();
//调用文件y.h中的函数f
y.f();
}
名字空间实质上是一个作用域。