文件重界说斗嘴的阐明与办理
引言
有时候看到论坛上有人问编译时重界说现象的问题。这个问题与头文件包括斗嘴有关,改一改相关头文件包括就会让问题消失。我在这里要以 <windows.h> <winsock.h> <winsock2.h>这3个头文件为例阐明为什么会发生这种原因;然后给出一种不会发生斗嘴的做法;最后就此例的阐明给出结论。本文对付已经知道斗嘴原因的读者是多余的,但对付一时没有时间去解的人照旧有必然的参考代价的。
一个重定名的例子
先写一个socket根基操纵类:
// SocketBase.h
#ifndef _SOCKET_BASE_H_
#define _SOCKET_BASE_H_
#include <winsock2.h>
#pragma comment(lib, "ws32_2.lib")
class Socket
{
};
#endif
写一个TCP监听类,它从Socket派生:
// TcpListener.h
#ifndef _TCP_LISTENER_H_
#define _TCP_LISTENER_H_
#include "SocketBase.h"
class TcpListener : Socket
{
};
#endif
在基于MFC的工程顶用 TcpListener 监听客户毗连,同时这个处所必要用到 Windows 某些头文件。
#include "stdafx.h"
#include "TcpListener.h"
void fun()
{
TcpListener* listen = new TcpListener;
……
}
下面是头文件包括干系:
Stdafx.h -> windows.h -> winsock.h winsock2.h
TcpListener.h -> SocketBase.h -> winsock2.h
编译,呈现N多重界说错误。这个错误与stdafx.h中的 windows.h 和TcpListener.h 的 winsock2.h 有关,下面说两种消除错误的要领。
针对本工程中消除编译
错误发生的原因是 windows.h 中有:
#include <winsock.h>
#include <winsock2.h>
发生重界说的是 windows.h 中的 winsock.h 相关界说与 TcpListener.h 中 winsock2.h 相关界说斗嘴。沟通头文件是不会斗嘴的,因为有 "#ifndef #define …. #endif";假如windows中只包括一个winsock2.h就不会发生重界说了。
此刻我们只要把 SocketBase.h 中的 "include <winsock2.h> 和 #pragma…"注释了就编译通过了。但颠末注释的 SocketBase.cpp 与 TcpListener.cpp 单独编译就通不外了。这种只是针对特定的情况下办理问题,我们得想一个较量专业的步伐。
一个可被接管的办理要领
Winsock2.h 与 windows.h 中的 winsock.h 相关项的重界说要在 SocketBase.h 中制止。在 SocketBase.h加一些编译条件就可以做到这一点,颠末修改的 SockBase.h 如下:
#ifndef _SOCKET_BASE_H_
#define _SOCKET_BASE_H_
#ifndef _WINSOCKAPI_ // 没有包括winsock.h
#define _WINSOCKAPI_ // 制止再包括winsock.h
#ifndef _WINSOCK2API_ // 没有包括winsock2.h
#define _WINSOCK2API_ // 制止再包括winsock2.h
#include <winsock2.h>
#pragma comment(lib, "ws32_2.lib")
#endif
#endif
class Socket
{
};
#endif
颠末这样修改,就能做到 winsock.h 与 winsock2.h 中的相关项重界说了。
结论
通过对上述例子的阐明办理,同样在其它雷同的问题中合用。假如有更简朴的要领制止重界说的环境呈现,请汇报我一下。
参考
Win32 sdk中的 windows.h;
Win32 sdk中的 winsock.h;
Win32 sdk中的 winsock2.h;