2012-05-27 57 views
2

我知道是怎麼回事,但我不知道如何解決這個問題:多重定義,如何原型std :: map?

的main.cpp

#include "Win32.h" 

int main() { 
    return 0; 
} 

Win32.h

#include <windows.h> 
#include <map> 

#ifndef WIN32_H_ 
#define WIN32_H_ 

namespace W32 { 

class Win32;      // Pre-Declaration 
std::map<HWND, Win32 *> windowMap; // Handle to Class instance mapping 

class Win32 { 
    public: 

     Win32(); 
     virtual ~Win32(); 

    protected: 

    private: 

}; // Class Win32 

} // namespace W32 

#endif // WIN32_H_ 

Win32.cpp

#include "Win32.h" 


namespace W32 { 

Win32::Win32() { 
} 

Win32::~Win32() { 
} 

} /* namespace W32 */ 

錯誤消息:

src\Win32.o: In function `Win32': 
    D:\Dev\Projects\Eclipse\OpenGL3\Debug/../src/Win32.cpp:7: multiple definition of `W32::windowMap' 
    src\main.o:D:\Dev\Projects\Eclipse\OpenGL3\Debug/../src/main.cpp:14: first defined here 

好吧,我知道std::map<HWND, Win32 *> windowMap;出現在更多的一個文件中,並且因爲它包含在多個文件(main.cpp/Win32.cpp)中,導致它被重新定義。我對std :: map還是有點新鮮。我需要做的是原型windowMap,但我不知道的是如何?我認爲這是當我抓住這段代碼。 Win32類需要能夠使用它,但它必須被聲明才能這樣做,但我所擁有的不是這樣做的,我無法找到正確的方法來獲得正確的有關如何正確轉發申報std::map<HWND, Win32 *> windowMap的信息。

+0

也許'extern'? –

+0

除了'Win32'外,還有其他的代碼需要使用'windowMap'嗎? – hmjd

+0

關於使用像'std :: map'這樣的非POD類型的全局實例,您可能需要閱讀[this point](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables)的Google C++風格指南。 – 2012-05-28 11:01:05

回答

4
std::map<HWND, Win32 *> windowMap; 

是一個定義,所以你打破一個定義規則。你需要把這些變量extern

extern std::map<HWND, Win32 *> windowMap; 

,並在單一實施文件中定義它:

Win32.h

#include <windows.h> 
#include <map> 

#ifndef WIN32_H_ 
#define WIN32_H_ 

namespace W32 { 
    class Win32;      // Pre-Declaration 
    extern std::map<HWND, Win32 *> windowMap; // Handle to Class instance mapping 
    //... 
}; // Class Win32 

} // namespace W32 

#endif // WIN32_H_ 

Win32.cpp

#include "Win32.h" 
namespace W32 { 
    std::map<HWND, Win32 *> windowMap; // Handle to Class instance mapping 
    //... 
} /* namespace W32 */ 
+0

'extern',每天學習新東西。固定。謝謝!! – Quade2002

+0

@Quade2002樂意幫忙! –

1

以下是定義,而不是聲明

std::map<HWND, Win32 *> windowMap; 

定義go in cpp files;在標題中你需要一個聲明,像這樣:

extern std::map<HWND, Win32 *> windowMap; 

定義

std::map<HWND, Win32 *> windowMap; 

在cpp文件應該去。否則,包含具有定義頭的每個cpp文件將定義自己的windowMap,導致您看到的鏈接器錯誤。

0

純C++方法是使:

std::map<HWND, Win32 *> windowMap" 

的Win32類的static構件。另外,忘記file.h以及file.cpp,爲簡單起見,幾乎所有核心​​開發者都棄用它。你的代碼太短了,所以一切都應該包含在頭文件中,特別是在你編寫框架的時候。

你的問題彈出了靜態成員存在於C++中的原因。此外定義這張地圖extern並不是一個好習慣,因爲你必須在某個地方隱藏真實的定義,也許在一個不太相關的地方。

最後,我已經試過這樣的設計已經時,Windows處理程序的函數被調用以異步方式...

1 - 你將在競爭狀態運行,如果超過一個窗口在同一有源時間。

2 - 事實上你只要你撥打賽跑條件CreateWindow功能,因爲它使調用你的窗口消息處理程序抽水,在你的後面,你不知道HWND值尚未

3-如果您嘗試在地圖上同時嘗試insert/read/remove,您將運行競賽條件,這實際上是一種相當常見的操作。