我有以下代码:
标题文件:
#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::string
,std::initializer_list
等一些标准类,来自<stdint.h>
的类型。这段代码编译,为什么头文件在源代码中看到导入的头文件?
答案 0 :(得分:2)
因为其他库标题后包含此源文件。尝试将其移至顶部,您将收到编译器错误。
这就是#include
的作用 - 它只是复制头文件内容并将其粘贴到#include
位置。
答案 1 :(得分:2)
预处理程序指令#include
只是“header”文件(或任何其他文件)的文本替换(“复制粘贴”)到包含#include
指令的文件中。最后,当包含所有内容时,您最终得到一个扁平的线性文本文件。毫无疑问,以后(下面)中包含的所有内容都可以看到之前的所有内容(上图)。
答案 2 :(得分:2)
在C ++中,头文件通过获取头文件的文本并将其放入#include
位置的源文件中来工作。*在这种情况下,在包括"client_server.h"
之前,包括<stdint.h>
,<string>
和<initializer_list>
。因此编译器已经在头文件之前看到了所有这些。
最佳做法通常是在任何其他人之前包含您自己单位的头文件,这样您就可以确保从头文件中包含您需要的所有内容,并且不会意外地导致其他任何人出现此问题使用标题。
*从技术上讲,我很确定它只包含头文件的标记,而不是实际的源包含,但在大多数情况下没有区别。