多个定义,如何原型std :: map?

时间:2012-05-27 20:27:46

标签: c++ class forward-declaration

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

的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

的信息

3 个答案:

答案 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.hfile.cpp一起,为了简单起见,几乎每个核心开发人员都弃用了它。你的代码很短,因此所有内容都应该包含在标题中,尤其是在编写框架时,就像你似乎那样。

你的问题突然出现了C ++中存在静态成员的原因。此外,定义此地图extern并不是一种好的做法,因为您还必须在某处隐藏真实的定义,可能在不太相关的地方。

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

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

2-事实上,只要你调用CreateWindow函数就会遇到竞争条件,因为它会在你的后面调用你的Windows消息处理程序,而你却不知道{ {1}}值

3-如果你同时在地图中尝试HWND,你将会遇到竞争条件,这实际上是一种非常常见的操作。