2

我知道发生了什么,但我不知道如何解决这个问题:

主文件

#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

4

3 回答 3

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 */
于 2012-05-27T20:31:13.670 回答
1

以下是定义,而不是声明

std::map<HWND, Win32 *> windowMap;

定义在 cpp 文件中;在标题中,您需要一个声明,如下所示:

extern std::map<HWND, Win32 *> windowMap;

定义

std::map<HWND, Win32 *> windowMap;

应该放在cpp文件中。否则,每个包含带有定义的标头的 cpp 文件都将定义自己的windowMap,从而导致您看到的链接器错误。

于 2012-05-27T20:31:36.277 回答
0

纯 C++ 方法是:

std::map<HWND, Win32 *> windowMap"

Win32 类的static成员。此外,忘记file.h旁边的 with file.cpp,为了简单起见,几乎每个核心开发人员都已弃用它。您的代码很短,因此所有内容都应包含在标头中,尤其是在您似乎正在编程框架时。

您的问题弹出了 C++ 中存在静态成员的原因。此外,定义此地图extern不是一个好习惯,因为您还必须将真实定义隐藏在某个地方,也许是在一个不太相关的地方。

最后,我已经尝试过这种设计,Windows 处理程序的函数以异步方式调用......

1- 如果多个窗口同时处于活动状态,您将在竞态条件下运行。

2-事实上,只要你调用CreateWindow函数,你就会运行一个竞争条件,因为它会在你的背后调用你的 windows 消息泵处理程序,而你还不知道HWND

3- 如果您同时尝试insert/read/remove在地图中运行,您将运行竞态条件,这实际上是一个很常见的操作。

于 2012-05-28T10:48:05.150 回答