C++ 是否包含包含的头文件包含的所有头文件?

Does C++ include all headers a included header file includes?

在这个示例代码中,我有 3 个文件:

testHeader.h:

void hello() {  }

file1.h:

#include "testHeader.h"
#include <iostream>
void sayHi() { std::cout << "hi" << std::endl; }

file2.h:

#include "file1.h"
void sayHello() { std::cout << "hello" << std::endl; }

如果 file1.h 包含 testHeader.hfile2.h 包含 file1.htestHeader.h 及其功能是否可以在 file2.h 中访问? <iostream> 及其函数呢?

除非以奇怪的方式受到预处理器守卫的保护,是的,你得到了它们。 #include 很大程度上是一个预处理器技巧,大致相当于将包含的文本转储到源代码中,并且它是可传递的;如果你 #include <a.h>,你会得到 a.h 的扩展形式,包括它的所有包含的预处理器扩展形式,它们的所有包含等等,等等,无限,在一次通过中。

请注意,明确包含您直接依赖的所有内容仍然是个好主意;当然,其他 .h 文件今天可能 #include <vector>,但如果它们不是公开的 API 的必要部分,则不能保证下一个版本会有它们。

还值得注意的是,预处理器包含防护 (and/or #pragma once) 几乎普遍用于表示 .h 文件的内容不会被包含两次(按照惯例,不是保证;如果 .h 文件写得不好,或者设计用于多次包含不同预处理器设置的怪异文件,则不会遵守); re-including 在 .cpp 中的 header 几乎没有成本,它已经从您包含的 .h 中获得。在较旧的编译器上,没有 #pragma once 并且没有对包含守卫的特殊处理,它可能必须第二次加载 header ,查看守卫,并且在第二次包含时不转储任何内容;许多较新的编译器足够聪明,甚至可以避免这种成本。重点是,不要试图通过避免冗余 #includes 来进行优化;每个文件都应该包含该文件中所用内容所需的完整 #include 集,不多也不少。

如果您使用较旧的编译器,没有#pragma once,请尝试执行以下操作。

--- file1.h ---

#ifndef FILE1_H
#define FILE1_H

#include "testHeader.h"
#include <iostream>
void sayHi();

#endif

--- file1.cpp ---

#include "file.h"
void sayHi() { std::cout << "hi" << std::endl; }

--- file2.h ---

#ifndef FILE2_H
#define FILE2_H

#include "file1.h"
#include <iostream>
void sayHello();

#endif

你不应该在 HEADER 文件中创建函数体。对于同一功能的多个链接,它可能会导致编译错误。请将函数的原型和函数体分别写到Header和Source文件中。