2009-07-27 21 views
3

メッセージ専用のウィンドウクラスを作成しました。これらのハンドルを持つオブジェクトに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*>を使用していることを私がやろうとしている

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

私がしようとすると、マップに追加するには、プログラムがクラッシュします。私は、3つの異なる形式を試してみた、そしてそれらはすべて同じエラーを与える:それぞれのケースで

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

を、そこにクラッシュがコールで発生します_Parent(_Myhead)を返そうとする_Root()に; _Parent(_Myhead)は、_Myheadがヌルであるために失敗する(_Nodepref)(*_Myhead)._Parentを返します。

地図を初期化するにはどのようにすればいいですか?ヘッドがnullでなく、クラッシュすることなく挿入できますか?私がこれをひどく説明してくれれば謝ります - 私はC++を初めて使っています。

+0

挿入を呼び出す場所にコードを投稿できますか?それ以前の行も? –

+3

あなたのコードからは、地図は静的ではありません。 –

+0

@Neil:良い点。それは元の - 固定されています。 – Simon

答えて

0

私のC++は少し錆びていますが、あなたの.cppファイルにその行がある理由はないと思います。実際、静的なメンバーではないので、どのような振る舞いにつながるのかよく分かりません。しかし、私が言ったように、私は錆びている - 私は何かを逃している可能性があります。

+0

申し訳ありません、ここに「静的」を入れるのを忘れてしまいました。私たちのコードでは、静的です。 – Simon

1

初期化する必要はありません。デフォルトで初期化する必要があります。

6

静的に初期化された別のオブジェクトのコンストラクタから使用していますか?

読むC++よくある質問Liteは - 10.12 What's the "static initialization order fiasco"?

+0

良い点 –

+0

私はそれを信じていませんが、それは私が目にする面白い(そしてひどい)問題です。それを指摘してくれてありがとう! – Simon

1

ただ、好奇心のうち。ウィンドウのハンドルはnullではありませんか?ウィンドウハンドルがnullに戻った場合、挿入は失敗するためです。

+0

2回目(重複しているため)、彼が求めている問題は発生しません。 –

+0

問題は、ウィンドウハンドルがnullかどうかに関係なく発生します。 – Simon

1

元の問題は既に解決されている可能性がありますが、私は(静的な部分がない)同様の問題に遭遇してしまいます。私は関数の中にマップを持っていましたが、それをクラス変数に移動しました。私はまた、マップに挿入するときにクラッシュしました。コンパイルされたすべてのオブジェクトを削除し、最初からコンパイルを再開する必要があることが判明しました。その後、すべてが期待通りに機能します。

0

これは間もなく解決されていると思われますが、参考にしておきましょう。実際の問題の解決策は次のとおりです。カスタムデータを任意のウィンドウのGWL_USERDATAフィールドに保存できます(:: SetWindowLong私が正しく覚えていればAPI関数)。 CMyClassポインタをマップ経由でHWNDに関連付けるのではなく、そこに置くと、地図はまったく必要ありません。高価ではなくポインタを型キャストするだけでよいので、より効率的ですマップルックアップ。

関連する問題