我知道发生了什么,但我不知道如何解决这个问题:
的main.cpp
#include "Win32.h"
int main () {
return 0;
}
Win32.h
#include <windows.h>
#include <map>
#ifndef WIN32_H_
#define WIN32_H_
namespace W32 {
class Win32; // Pre-Declaration
std::map<HWND, Win32 *> windowMap; // Handle to Class instance mapping
class Win32 {
public:
Win32();
virtual ~Win32();
protected:
private:
}; // Class Win32
} // namespace W32
#endif // WIN32_H_
Win32.cpp
#include "Win32.h"
namespace W32 {
Win32::Win32() {
}
Win32::~Win32() {
}
} /* namespace W32 */
错误讯息:
src\Win32.o: In function `Win32':
D:\Dev\Projects\Eclipse\OpenGL3\Debug/../src/Win32.cpp:7: multiple definition of `W32::windowMap'
src\main.o:D:\Dev\Projects\Eclipse\OpenGL3\Debug/../src/main.cpp:14: first defined here
好的,我知道std::map<HWND, Win32 *> windowMap;
出现在更多的一个文件中,并且因为它包含在多个文件(main.cpp / Win32.cpp)中,所以它被重新定义。我还是std :: map的新手。我需要做的是原型windowMap
,但我不知道的是怎么样?我以为这就是我抓住这段代码的时候。 Win32类需要能够使用它,但它必须被声明才能这样做,但我所拥有的不是这样做的方式,我不知道该寻找什么来获得正确的有关如何正确转发声明std::map<HWND, Win32 *> windowMap
。
答案 0 :(得分:4)
std::map<HWND, Win32 *> windowMap;
是一个定义,因此您打破了一个定义规则。您需要创建变量extern
:
extern std::map<HWND, Win32 *> windowMap;
并在单个实现文件中定义它:
Win32.h
#include <windows.h>
#include <map>
#ifndef WIN32_H_
#define WIN32_H_
namespace W32 {
class Win32; // Pre-Declaration
extern std::map<HWND, Win32 *> windowMap; // Handle to Class instance mapping
//...
}; // Class Win32
} // namespace W32
#endif // WIN32_H_
Win32.cpp
#include "Win32.h"
namespace W32 {
std::map<HWND, Win32 *> windowMap; // Handle to Class instance mapping
//...
} /* namespace W32 */
答案 1 :(得分:1)
以下是 deifnition ,而不是声明:
std::map<HWND, Win32 *> windowMap;
定义进入cpp文件;在标题中,您需要声明,如下所示:
extern std::map<HWND, Win32 *> windowMap;
定义
std::map<HWND, Win32 *> windowMap;
应该进入cpp文件。否则,包含带定义的头的每个cpp文件将定义其自己的windowMap
,从而导致您看到链接器错误。
答案 2 :(得分:0)
纯C ++方法是:
std::map<HWND, Win32 *> windowMap"
Win32类的static
成员。此外,忘记file.h
和file.cpp
一起,为了简单起见,几乎每个核心开发人员都弃用了它。你的代码很短,因此所有内容都应该包含在标题中,尤其是在编写框架时,就像你似乎那样。
你的问题突然出现了C ++中存在静态成员的原因。此外,定义此地图extern
并不是一种好的做法,因为您还必须在某处隐藏真实的定义,可能在不太相关的地方。
最后,我已经尝试过这个设计,Windows处理程序的函数以异步方式调用...
1-如果同时有多个窗口处于活动状态,您将在竞争条件下运行。
2-事实上,只要你调用CreateWindow
函数就会遇到竞争条件,因为它会在你的后面调用你的Windows消息处理程序,而你却不知道{ {1}}值
3-如果你同时在地图中尝试HWND
,你将会遇到竞争条件,这实际上是一种非常常见的操作。