为了方便的编写代码,c++提供了多文件编写的方式,函数和类存在声明和定义两种,c++可以通过申明来查找定义。例如,以下几个文件:
/*test.h*/
#pragma once
#include <iostream>
void show();
/*test.cpp*/
#include "test.h"
using namespace std;
void show()
{
cout << "hello world" << endl;
}
/*main.cpp*/
#include "test.h"
using namespace std;
int main()
{
show();
return 0;
}
在test.h文件中,我们写了一个show函数的申明,在test.cpp中通过引号的方式包含了头文件test.h就相当于将test.h中的所有代码全部复制到test.cpp中,然后就可以对已经申明的show函数进行定义,最后在main中包含头文件。在main中包含了头文件以后依然是相当于将test.h中的所有内容全部复制到main.cpp中,也就是说,此时在main.cpp文件中就存在了show函数的申明。最后我们在调用show函数时,编译器会自动通过函数的申明在项目中去查找函数的定义,然后再去实现。
对于头文件的写法,有需要注意的事项:
在代码编写的过程中很难保证同一个头文件在一个文件中被包含多次,也就是说我们可能会因为疏忽在main.cpp文件中两次包含test.h,此时在main.cpp中就会出现show函数的两次申明,就会出现错误。为了防止出现这样的问题我们会在头文件的第一行加上#pragma once这个宏来防止头文件被重复包含。
但是#pragma once这个宏只在windows平台下可以使用,它不支持其它平台。相对于这个方式头文件重复包含的宏,使用#ifndef的方式更为常见,如下:
/*test.h*/
#ifndef TEST_H__
#define TEST_H__
#include <iostream>
void show();
#endif
我们可以将test.h中的代码修改为这种方式。宏#ifndef可以理解为如果没有包含某某头文件,而#endif是和#ifndef配套出现的语句,意思为跳出。即在#ifndef处,系统会检测是否定义了对应文件,如果已经定义了就会自动跳到#endif处继续向下执行。如果没有定义,就会执行#ifndef下面的语句。配合上#define宏,如果是第一次包含头文件,系统就会定义一个宏,当发生重复包含时,系统就会检测到已经包含了对应的宏,就会自动到#endif处。
对于此处的宏有没有语法上的严格定义,但是和#define取别名时一样有着认为的默认规则:
对于文件命名时,头文件和对应定义的源文件的名字是一样的
#ifndef和#define宏的后面应该采用对应的文件名做标识,且全部大写,文件名字和文件名后缀之间用"_"符号进行隔开