C++ C++;重新定义头文件(winsock2.h)
如何防止头文件包含两次?问题是我将包含在MyClass.h中,然后我将MyClass.h包含在许多文件中,因此它包含多次,并出现重新定义错误。如何预防 我用了一次“pragma”而不是“include guard”,我想这没关系 MyClass.h:C++ C++;重新定义头文件(winsock2.h),c++,header,redefinition,C++,Header,Redefinition,如何防止头文件包含两次?问题是我将包含在MyClass.h中,然后我将MyClass.h包含在许多文件中,因此它包含多次,并出现重新定义错误。如何预防 我用了一次“pragma”而不是“include guard”,我想这没关系 MyClass.h: // MyClass.h #pragma once #include <winsock2.h> class MyClass { // methods public: MyClass(unsigned short port);
// MyClass.h
#pragma once
#include <winsock2.h>
class MyClass
{
// methods
public:
MyClass(unsigned short port);
virtual ~MyClass(void);
};
通过使用“收割台防护装置”:
\ifndef MYCLASS\u H
#定义MYCLASS_H
//这是不必要的,请参见注释。
//#布拉格语一次
//MyClass.h
#包括
类MyClass
{
//方法
公众:
MyClass(无符号短端口);
虚拟~MyClass(void);
};
#恩迪夫
您应该使用收割台护罩
将这些行放在头文件的顶部
#ifndef PATH_FILENAME_H
#define PATH_FILENAME_H
在底部
#endif
#pragma once
即使在MS编译器上也很脆弱,许多其他编译器不支持它。正如许多其他人所提到的,使用include-guard是一条可行之路。不要一次使用pragma,这会让你的生活更轻松。\pragma一次
基于文件名的完整路径。因此,您可能有两个相同的MyClass.h或Winsock2.h副本,位于不同的目录中。是执行此操作的标准方法。不是,这意味着并非所有编译器都支持它。在
之前包含
时会导致此问题。请尝试将
包含在
之后的包含列表安排好,或先定义\u WINSOCKAPI\u
:
#define _WINSOCKAPI_ // stops windows.h including winsock.h
#include <windows.h>
// ...
#include "MyClass.h" // Which includes <winsock2.h>
#定义WINSOCKAPI//停止windows.h,包括winsock.h
#包括
// ...
#包括“MyClass.h”//其中包括
另请参见。我不会只使用文件名 但是 我一直使用后缀guid。几年前,我遇到了一个非常糟糕的代码库,它有不同的头文件,具有相同的文件名,并且包含guard。有问题的文件定义了一个同名的类。如果只使用名称空间就好了。一些项目编译了一些没有。使用独特的保护是区分标题及其内容的解决方案的一部分
在使用Visual Studio的Windows上使用guidgen.exe,在Linux uuidgen-t上使用guidgen.exe。我在尝试拉取第三方软件包时遇到了这个问题,该软件包的头文件中显然包含了Windows.h。在项目级别定义
\uWinsockapi
比费力地解决问题要容易得多(更不用说更易于维护)。哦,Windows的丑陋。。。包含的顺序在这里很重要。您需要在windows.h之前包含winsock2.h。由于windows.h可能包含在预编译头(stdafx.h)中,因此您需要在其中包含winsock2.h:
#include <winsock2.h>
#include <windows.h>
#包括
#包括
我发现这个链接有一个非常适合我的替代方案:
#define _WINSOCKAPI_ // stops windows.h including winsock.h
#include <windows.h>
#include <winsock2.h>
#定义WINSOCKAPI//停止windows.h,包括winsock.h
#包括
#包括
我很难找到问题发生的地方,但是通过添加define,我可以在没有弄清楚的情况下构建它 正如其他人所建议的,问题在于
WinSock2.h
之前包含windows.h
时。因为windows.h
包括winsock.h
。不能同时使用WinSock2.h
和winsock.h
解决方案:
- 在
之前包括windows.h
。对于预编译头,您应该在那里解决它。对于简单的项目,这很容易。然而,在大型项目中(尤其是在编写可移植代码时,没有预编译头),这可能非常困难,因为当包含带有WinSock2.h
的头时,WinSock2.h
可以从其他头/实现文件中包含windows.h
- 在
或项目范围之前定义windows.h
。但它会排除你可能需要的许多其他东西,你应该自己把它包括进去WIN32\u LEAN\u和\u MEAN
- 在
或项目范围之前定义windows.h
。但当您包含\u WINSOCKAPI
时,会收到宏重新定义警告WinSock2.h
- 当
对您的项目足够时(在大多数情况下),请使用winsock.h
而不是windows.h
。这可能会导致更长的编译时间,但可以解决任何错误/警告WinSock2.h
让我知道这是否有意义。我检查了递归包含,我发现头文件(递归地)包含一些
\include“windows.h”
和\include“Winsock.h”
并编写了一个\include“Winsock2.h”
。在这个文件中,我添加了#include“Winsock2.h”
作为第一个include
耐心一点,逐个查看包含并建立此顺序,首先#包含“Winsock2.h”
,然后#包含“windows.h”
在我的项目中(我使用VS 2008 SP1)工作下一个解决方案:
头文件:
//myclass.h
#pragma once
#define _WINSOCKAPI_
#include <windows.h>
其中#include“winsock2class.h”表示实现winsock2.h的类:
//winsock2class.h
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "Ws2_32.lib")
//winsock2class.h
#包括
#包括
#pragma注释(lib,“Ws2_32.lib”)
在VS 2015中,以下各项将起作用:
#define _WINSOCKAPI_
但以下情况不会:
#define WIN32_LEAN_AND_MEAN
实际上,我遇到了一个问题,我必须将winsock2.h定义为第一个包含,似乎它与其他包中的包含有其他问题。希望这对遇到相同问题的人有所帮助,不仅仅是windows.h,还有all includes。您已经使用了一次#pragma,所以应该只包含一次。您的编译器不会
//myclass.h
#pragma once
#define _WINSOCKAPI_
#include <windows.h>
//myclass.cpp
#include "Util.h"
#include "winsock2class.h"
#pragma comment(lib, "Ws2_32.lib")
//winsock2class.h
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "Ws2_32.lib")
#define _WINSOCKAPI_
#define WIN32_LEAN_AND_MEAN