如何初始化静态 std::map?

3

我创建了一个仅用于消息的窗口类,并尝试将HWND映射回具有这些句柄的对象。我正在尝试使用该类私有静态std :: map <HWND,CMyClass *&gt; 来完成此操作,如下所示:

MyClass.h:

class CMyClass
{
    ...

private:
    HWND        m_hWnd;
    HINSTANCE   m_hInstance;
    LPCSTR      m_szClassName;

    static std::map<HWND, CMyClass*> s_mapHandles;

    ...
};

MyClass.cpp:

std::map<HWND, CMyClass*> CMyClass::s_mapHandles;

但是当我尝试添加到地图时,程序会崩溃。我尝试了三种不同的形式,它们都给出了相同的错误:

...
m_hWnd = ::CreateWindowEx(0, m_szClassName, "Message Window", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, m_hInstance, 0);
s_mapHandles.insert(pair<HWND, CMyClass*>(m_hWnd, this));

或者

...
s_mapHandles.insert(s_mapHandles.end(), pair<HWND, CMyClass*>(m_hWnd, this));

甚至更多。
...
s_mapHandles[m_hWnd] = this;

在每种情况下,崩溃发生在调用_Root()时,它试图返回_Parent(_Myhead); _Parent(_Myhead)返回(_Nodepref)(*_Myhead)._Parent,但由于_Myhead为空,因此失败。
我该如何初始化地图,使其头部非空并且可以插入东西而不会崩溃?如果我解释得不好,请原谅 - 我是C ++的新手。

你能发一下调用insert的代码吗?还有它之前的几行代码? - Jaime Garcia
3
从您的代码中可以看出,这个 map 没有被声明为静态的。 - anon
@Neil:好观点。这已经在原始文件中修复了。 - Simon
6个回答

6
你是从另一个静态初始化的对象的构造函数中使用它吗?
阅读C++ FAQ Lite - 10.12“什么是'静态初始化顺序混乱'?”(链接)

我不这么认为,但那是一个有趣(也很糟糕)的问题,我会留意的。谢谢你指出来! - Simon

1
原始问题可能已经解决,但我碰巧遇到了类似的问题(没有静态部分)。我曾经将地图放在函数内部,然后将其移动到类变量中。当我向地图插入内容时,也会出现崩溃的情况。结果发现,我需要删除所有编译对象并从头开始重新编译。然后一切都按预期工作。

1

您不需要进行任何初始化,它应该默认初始化。


1

只是出于好奇,窗口句柄不为null吗?因为如果窗口句柄返回为null,则插入操作将失败。


只有第二次(因为它是一个重复的)- 这不会引起他所询问的问题。 - anon
无论窗口句柄是否为空,问题都会发生。 - Simon

0

我的C++有点生疏,但我认为没有理由在你的.cpp文件中加入那行代码。实际上,由于它不是静态成员,我不确定那会导致什么样的行为。但正如我所说,我有点生疏,可能会漏掉一些东西。


抱歉,这里忘记加上“static”了。在我们的代码中,它是静态的。 - Simon

0

这个问题可能已经在此期间得到解决,但仅供参考:这是另一个解决实际问题的解决方案:您可以将自定义数据存储在任何窗口的GWL_USERDATA字段中(如果我记得正确,使用::SetWindowLong API函数)。如果您将CMyClass指针放在那里而不是通过映射与HWND相关联,那么您根本不需要映射,而且更有效率,因为您只需要对指针进行类型转换,而不是昂贵的映射查找。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接