相信每个C++
程序员都有这样的经历:在一个大工程中不知道是否需要#include
某个头文件,又或者干脆在每一个头文件中都写上#pragma once
或者使用#ifndef <标识>
+#define <标识>
+#endif
三板斧。
或许你已经发现了,C++
中的#include
不同于其他语言(如Java
和Python
的import
),它并不那么友善,稍不留意就会导致编译错误。其实不仅如此,如果对于大工程,随意使用include
将会无声无息地一点点拖慢程序的编译速度。
在头文件中声明函数或者类,然后在对应的cpp
文件中写对应的实现,这显然是C++
编程的潜规则
。这时候,应该会有人跳出来说,“不这样也行啊,而且会更方便。”甚至有些“高手”说,这个#include
能做的事可多了,比如用来加载配置表。
//setting.h
int a = 5;
int b = 6;
//main.cpp
#include
using namespace::std;
int wow()
{
#include "test.h"
return a + b;
}
int main()
{
std::cout<
程序的运行结果是11
,可能你会相当惊讶。但如果你已经知道#include
其实不过是将指定文件内容展开,然后再编译而已,那肯定能轻松理解这个赢巧奇技
。当然如果是导入配置或者宏一般不会这么做,而应该是在文件开头#include
。
因此我们使用#include
,一般是一下两个目的:
typedef
,#define
,const
变量等宏配置;cpp文件
中定义或者静态库定义的函数或者类。阅读以下程序代码:
//test.h
int func()
{
return 0;
}
//test2.h
#include "test.h"
int func2()
{
return func() + 1;
}
//main.cpp
#include
#include "test.h"
#include "test2.h"
using namespace::std;
int main()
{
std::cout<
当你点运行的时候,你很可能会惊讶地看到以下的文字:
test/test.h:1: error: redefinition of ‘int func()’
为什么会变成这样呢?其实很简单,在编译器看来,上面的代码其实等同于下面的:
//FuncA.h
int FuncA()
{
return 100;
}
//main.cpp
#include
int func()// ←由#include "test.h"展开得到
{
return 0;
}
int func()// ←由#include "test2.h"展开得到,而test2.h中又有一个#include "test.h",再次展开得到
{
return 0;
}
#include "test.h"// ←由#include "test2.h"展开得到
int func2()
{
return func() + 1;
}
using namespace::std;
int main()
{
std::cout<
这样,错误原因就很明显了吧,函数重定义冲突。这再次验证了C++
的经典编程规范——“头文件只能声明
函数,函数的定义
要放到对应的cpp文件
中,只能#include
该头文件,而不能#include
其cpp源文件
。”
阅读下面的代码:
//other.cpp
int func()
{
return 5;
}
//main.cpp
#include
int func();//←本应该是#include "other.h"
int main()
{
std::cout<
既然上面说了,include
其实不过是将指定文件内容展开,那么我直接像上面那样把本应该出现的#include "other.h"
,直接替换为它的内容,不就可以少写一个文件了吗?事实证明也是可行的。如果你是使用图形界面IDE进行编程的,那么你应该理解其背后都干了些什么。实际上IDE偷偷运行了类似下面的命令:
g++ -c other.cpp
g++ -c main.cpp
g++ other.o main.o -o test
./test
g++
的-c
选项的含义为仅执行编译操作,而不进行连接操作。当然,我在这里并不是怂恿大家以后就不写#include
了,只是让大家明白背后的含义而举个不太恰当的例子,为了少些一个.h
头文件而惹来一堆不直观、不方便、难编译的麻烦,这显然是愚蠢至极的做法。
最后给大家看个不使用#include
的hello world
,其涉及的底层原理,可就不这么容易说明和理解了。
extern "C" {
int printf(const char * _Format, ...);
}
int main()
{
printf("hello word");
return 0;
}