为什么头文件会看到源文件的包含?

Why header file sees source file's includes?

本文关键字:源文件 包含 文件 为什么      更新时间:2023-10-16

我有以下代码:

头文件:

#pragma once
#include <uWS/uWS.h>
typedef __uint32_t ClientID;
typedef __uint16_t Port;
class ClientServer
{
public:
    ClientServer();
    ClientServer(const ClientServer&) = delete;
    ClientServer& operator=(const ClientServer&) = delete;
    ~ClientServer();
    bool run(const std::string& host, Port port);
    bool disconnect();
    bool isConnected(ClientID id);
    bool send(std::initializer_list<ClientID> idList, const std::wstring& message);
};

源文件:

#include <stdint.h>
#include <string>
#include <initializer_list>
#include "client_server.h"
ClientServer::ClientServer()
{
}

如您所见,头文件使用了一些 std 类,例如 std::stringstd::initializer_list<stdint.h> 中的类型。而这段代码编译,为什么头文件在源中看到导入的头文件?

因为此源文件包含在其他库标头之后。尝试将其移动到顶部,您将收到编译器错误。

这就是#include所做的 - 它只是复制头文件内容并将其粘贴到#include位置。

预处理器指令#include只是将"头"文件(或任何其他文件(的文本替换("复制粘贴"(到包含#include指令的文件中。最后,当包含所有内容时,您最终会得到一个平面线性文本文件。毫不奇怪,后面(下面(包含的所有内容都可以看到前面(上面(包含的所有内容。

在C++中,头文件的工作原理是获取头文件的文本并将其放入源文件中#include的位置。 在本例中,在包含 "client_server.h" 之前,包括 <stdint.h><string><initializer_list> 。因此,编译器在头文件之前已经看到了所有这些。

最佳做法通常是在任何其他文件之前包含您自己的单元的头文件,以便确保从头文件中包含所需的所有内容,并且不会意外地导致使用该头的任何其他人出现此问题。


* 从技术上讲,我相当确定它只包含头文件的标记,而不是实际的源代码包含,但在大多数情况下没有区别。