我们知道,在 C++ 中,函数只能定义一次,而在 cpp 文件中如果想使用其他 cpp 文件中定义了的函数,就必须声明,这样才能通过编译,然后链接器才会在调用函数时找到该函数的定义。那么当函数声明很多的时候,代码就会很臃肿。这时,我们就可以使用 .h 头文件,通过#include "头文件"
的方式,实现函数声明的功能。
先说下双引号""和尖括号<>的区别:
#include <xxx.h>
系统自带的头文件用尖括号括起来,这样编译器会在系统文件目录下查找。
#include “xxx.h”
用户自定义的文件用双引号括起来,编译器首先会在用户目录下查找,然后在到 C++ 安装目录(比如VC中可以指定和修改库文件查找路径,Unix和Linux中可以通过环境变量来设定)中查找,最后在系统文件中查找。
所以实际上,无论这个文件是 C++ 提供的还是自己编写的,使用 #include “文件名” 命令一定是正确的。但是,标准规定,包含 C++ 提供的标准头文件或系统头文件时应使用尖括号,包含自定义头文件时可使用双引号。 以后我们还是按照标准来写比较好。
在VS中,我们在 Header Files 下新建一个 .h 文件,会出现这句代码:
#pragma once
这个实际上是规定在 cpp 文件中引用这个 .h 文件只能 #include
一次。可能我们有疑问,为什么会有人多次 #include
同一个头文件呢?再说,函数声明多次也无所谓呀。
虽然函数能多次声明,但是如果在头文件中定义了结构体之类的,多次定义就会有问题。假设 a.h #include
了 b.h,而在 main.cpp 中同时#include
了 a.h 和 b.h,这样就相当于引用了 a.h 两次,此时如果没有那行代码就会报错。
还有另一种检查的方法,如下:
Log.h
#ifndef _LOG_H
#define _LOG_Hvoid Log(const char* message);#endif
Log.cpp
#include <iostream>
#include "Log.h"
#include "Log.h"void InitLog()
{Log("Initialized Log");
}
Log.cpp 经过预处理后的实际效果如下:
如果多次 #include
了 Log.h 文件,相当于在 cpp 文件中存在两段相同的代码,如图所示。加上检查语句之后,只有第一段代码高亮,因为此时 _LOG_H 还未被定义;而第二段代码变灰,这是因为前面已经定义了 _LOG_H 了,所以后面的代码不会执行。这样我们也能做到和 #pragma once
一样的功能,也就是只 #include
一次,但实际中更推荐使用 #pragma once
。