2013-01-14 126 views
2

我正在編寫一個遊戲框架,我試圖推廣和封裝與渲染器相關的平臺相關代碼,以便它使端口更容易一些。我試圖做到這一點,同時仍然有一個乾淨的方式來使用框架。我目前具有靜態變量和命名空間的問題......命名空間中的靜態變量

 
    // Renderer.h 

    namespace Renderer 
    { 
     static IRenderer* g_pRenderer = NULL; 

     static IRenderer* Get(void) { return g_pRenderer; } 

     static IRenderer* CreateD3DRenderer() 
     { 
      g_pRenderer = new RendererD3D(); // Derived from IRenderer 
      return g_pRenderer; 
     } 
    } 
main()

所以,我可以打電話CreateD3DRenderer(),並返回一個實例就好了; g_pRenderer自其創建並在其功能範圍內保留其值,但是,Renderer::Get()返回NULL。在g_pRenderer的init中刪除'static'會導致在其他文件中使用衝突。

發生了什麼事?

回答

2

首先,參數列表中的void僅在C中是必需的。在C++中,您只需編寫Get()

至於主要問題,static變量僅限於編譯單元。由於您將它們放在標題中,因此會爲包含它的每個編譯單元(即每個cpp文件)創建一個單獨的變量。當您刪除static部件時會出錯,因爲您有多個具有相同名稱的變量,從而導致鏈接錯誤。

如果您想要在多個文件之間共享單個變量,請使用extern。但是,這被認爲是不好的做法。你最好重構,所以你不需要像這樣的全局變量。

+0

我沒有任何其他變量使用相同的名稱。雖然在技術上,它包含了代碼所在的頭部後會重新聲明,所以我非常理解。但除此之外,這是該程序中此名稱的唯一變量。 – Sutanreyu

2

你應該保留的功能都定義在.cpp文件,而不是.h

正在發生的事情是,靜態時以那種方式被使用,函數或變量都被限制到.cpp文件,這意味着g_pRenderer在每個.cpp文件中不同。由於每個定義限制爲一個.cpp文件,所以不會發生多重定義。

您需要將其刪除才能使您的全局指針工作。你可以保持靜態的getter函數,但我會刪除它。您應該將函數的定義和全局變量移動到.cpp文件中,並在.h中保留每個文件的聲明。聲明該變量爲extern