文件中不包含头文件,但仍可以使用未包含的头文件中的 classes/functions

No header files included in file but can still use classes/functions from unincluded header files

下面是相关文件中的一些代码,称为 Global.h,它在其他头文件中使用并且似乎编译得很好:

#pragma once

enum SType {null, lab, assignment, testPrep};
enum Code {none, 123, 222, 333, 432};

template<typename D>
bool validate(D task = string, D date = string) {

    bool result = true;

    if (task.size() < 3) {
        cout << "Task too simple, please elaborate." << endl;
        result = false;
    }
    else if (task.size() > 50) {
        cout << "Task too detailed. Only 30 chars allowed." << endl;
        task.empty();
        result = false;
    }

if (date == "02/20/93") {
    date.empty();
    date = "My birthday!";
}

    return result;

}

如您所见,我可以在不声明使用命名空间或特定文件的情况下使用字符串和 ostream 对象。显然这意味着 Global.h 正在从其他地方获取信息,但我很好奇这些信息是从哪里来的?我一直认为,如果头文件已包含在文件本身的#include 指令中,那么头文件只会重新调整来自其他文件的代码,所以我不确定这是怎么发生的,并且很想知道发生了什么。

没有。只是包含此 Global.h 头文件的任何内容都必须已经 #includeing 所有必需的头文件。

有点简化:通过逻辑插入 #included 文件的内容代替 #include 语句本身来替换 #include 语句。编译翻译单元时,所有 #include 语句都以这种方式处理。好像所有 #include 语句在逻辑上都被引用文件的内容替换了。最终结果是一个单一的逻辑源文件,一个翻译单元,从头到尾编译。

所以,如果所有#include语句都以这种方式处理后,只要必要的头文件,<iostream>等,在逻辑翻译单元之前逻辑插入类 和从该头文件引用的 <iostream> 中的其他资源,该翻译单元将毫无问题地编译。与#include需要的头文件、<iostream>等是否是同一个头文件;或其他一些较早获得 #included 的头文件,其中 #includes 这些头文件;没关系。

的确,好的做法表明每个文件都应该明确 #include 其先决条件。但如果没有,只要其他一些头文件已经 #included,翻译单元仍然会编译。