如何初始化静态 std::map?
我创建了一个仅消息窗口类,并且尝试将 HWND 映射回具有这些句柄的对象。 我试图使用属于该类的私有静态 std::map
来做到这一点,如下所示:
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
为 null。
如何初始化地图,使其头部非空,并且我可以插入东西而不会崩溃? 如果我解释得不好,我很抱歉 - 我是 C++ 新手。
I've made a message-only window class, and I'm trying to map HWNDs back to the objects with those handles. I'm trying to do that using a private static std::map<HWND, CMyClass*>
belonging to the class, like this:
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;
but when I try to add to the map, the program crashes. I've tried three different forms, and they all give the same error:
...
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));
or
...
s_mapHandles.insert(s_mapHandles.end(), pair<HWND, CMyClass*>(m_hWnd, this));
or even
...
s_mapHandles[m_hWnd] = this;
In each case, there crash occurs at a call to _Root()
which tries to return _Parent(_Myhead)
; _Parent(_Myhead)
returns (_Nodepref)(*_Myhead)._Parent
which fails because _Myhead
is null.
How do I initialise the map, such that its head is non-null and I can insert things without it crashing? Apologies if I've explained this badly - I'm new to C++.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
只是出于好奇。 窗口句柄不为空吗? 因为如果窗口句柄返回为 null,则插入将失败。
Just out of curiosity. Is the window handle not null? Because if the window handle comes back as null then the insert will fail.
原来的问题可能已经解决了,但我碰巧遇到了类似的问题(没有静态部分)。 我曾经将映射放在函数内部,然后将其移至类变量中。 插入地图时我也遇到了崩溃。 事实证明,我需要删除所有已编译的对象并从头开始重新编译。 然后一切都会按预期进行。
The original problem may be already solved, but I happen to run in to similar problem (without the static part). I used to have the map inside of a function, then moved it to a class variable. I also got crashes when inserting to the map. It turns out that I needed to delete the all the compiled objects and restart compiling from scratch. Then everything works as expected.
您是否从另一个静态初始化对象的构造函数中使用它?
阅读 C++ FAQ Lite - 10.12 什么是“静态初始化顺序惨败”?
Are you using it from the constructor of another statically initialized object?
Read C++ FAQ Lite - 10.12 What's the "static initialization order fiasco"?
您根本不需要初始化它,它应该默认初始化。
You don't need to initialize it at all, it should be initialized by default.
这可能同时已经解决,但仅供参考:这是问题背后实际问题的另一个解决方案:您可以将自定义数据存储在任何窗口的 GWL_USERDATA 字段中(我相信使用 ::SetWindowLong API 函数,如果我记住正确)。 如果您将 CMyClass 指针放在那里,而不是通过映射将其与 HWND 关联起来,那么,您根本不需要映射,而且效率更高,因为您所需要做的就是对指针进行类型转换,而不是昂贵的映射地图查找。
This has probably been solved in the meantime, but just for reference: Here is another solution for the actual problem behind the question: You can store custom data in the GWL_USERDATA field of any Window (I believe using the ::SetWindowLong API function if I remember correctly). If you put your CMyClass pointer in there instead of associating it with the HWND via a map, well, you don't need the map at all, and it is more efficient since all you need to do is typecast the pointer instead of an expensive map lookup.
我的 C++ 有点生疏,但我认为没有任何理由在 .cpp 文件中包含该行。 事实上,由于它不是静态成员,我不确定这会导致什么样的行为。 但就像我说的,我生疏了——我可能会错过一些东西。
My C++ is a little rusty, but I don't think there's any reason for having that line in your .cpp file. In fact, since it's not a static member, I'm not sure what kind of behavior that would lead to. But like I said, I'm rusty - I could be missing something.