简体   繁体   中英

How do I initialize a static std::map?

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++.

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

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

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM