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

时间:2022-03-07 15:01:17

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:

我已经创建了一个仅消息窗口类,我正在尝试将HWND映射回具有这些句柄的对象。我正在尝试使用属于该类的私有静态std :: map ,如下所示: ,cmyclass>

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.

在每种情况下,在调用_Root()时都会发生崩溃,它会尝试返回_Parent(_Myhead); _Parent(_Myhead)返回(_Nodepref)(* _ Myhead)._由于_Myhead为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++.

如何初始化地图,使其头部非空,我可以在不崩溃的情况下插入内容?如果我解释得很糟糕,我会道歉 - 我是C ++的新手。

6 个解决方案

#1


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"?

阅读C ++ FAQ Lite - 10.12什么是“静态初始化命令惨败”?

#2


You don't need to initialize it at all, it should be initialized by default.

您根本不需要初始化它,默认情况下应该初始化它。

#3


Just out of curiosity. Is the window handle not null? Because if the window handle comes back as null then the insert will fail.

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

#4


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.

最初的问题可能已经解决,但我碰巧遇到了类似的问题(没有静态部分)。我曾经在一个函数里面有地图,然后将它移动到一个类变量。插入地图时我也遇到了崩溃。事实证明,我需要删除所有编译的对象并从头开始重新编译。然后一切都按预期工作。

#5


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.

我的C ++有点生疏,但我认为你的.cpp文件中没有任何理由。事实上,由于它不是静态成员,我不确定会导致什么样的行为。但就像我说的那样,我生锈了 - 我可能会遗漏一些东西。

#6


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.

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

#1


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"?

阅读C ++ FAQ Lite - 10.12什么是“静态初始化命令惨败”?

#2


You don't need to initialize it at all, it should be initialized by default.

您根本不需要初始化它,默认情况下应该初始化它。

#3


Just out of curiosity. Is the window handle not null? Because if the window handle comes back as null then the insert will fail.

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

#4


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.

最初的问题可能已经解决,但我碰巧遇到了类似的问题(没有静态部分)。我曾经在一个函数里面有地图,然后将它移动到一个类变量。插入地图时我也遇到了崩溃。事实证明,我需要删除所有编译的对象并从头开始重新编译。然后一切都按预期工作。

#5


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.

我的C ++有点生疏,但我认为你的.cpp文件中没有任何理由。事实上,由于它不是静态成员,我不确定会导致什么样的行为。但就像我说的那样,我生锈了 - 我可能会遗漏一些东西。

#6


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.

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