2012-01-31 122 views
1

我有一個名爲PooledResource的模板類。它爲我處理加載諸如紋理和聲音之類的東西,並確保我在事故中多次加載相同的東西。某種類型的資源總是處於某個子目錄中,我想讓它更容易加載,因此我決定添加一個靜態變量,以跟蹤特定類型資源的根文件夾。模板類的靜態變量的多重定義

template <typename T> 
class PooledResource 
{ 
public: 
    // ... 

    static const char* PathPrefix; 
    static ResourceTable myResourceTable; 


    static void load(const char* filename) 
    { 
     // Any attempt to use PathPrefix in here causes a compilation error 
     // All I want to do is use PathPrefix and filename to get the full 
     // path do a file and load it. 
    } 
}; 

template <typename T> 
const char* PooledResource<T>::PathPrefix = NULL; 

template <typename T> 
typename PooledResource<T>::ResourceTable PooledResource<T>::myResourceTable; 

這個想法是,我可以使用這個typedef'd版本的各種類型。例如,在PooledTexture.hpp我會:

typedef PooledResource<Texture> PooledTexture; 

PooledTexture.cpp我會:

template <> 
const char* PooledTexture::PathPrefix = "../assets/textures/"; 

這都將編譯和運行很好,如果我不嘗試在負載功能使用PathPrefix以上。當我用它雖然,我得到的錯誤是這樣的:

90 || CMakeFiles/game.dir/PooledTexture.cpp.o:(.data+0x0): multiple definition of `ag::PooledResource<sf::Texture>::PathPrefix' 
91 CMakeFiles/game.dir/lua/LuaFrame.cpp.o:/usr/include/c++/4.6/i686-linux-gnu/./bits/gthr-default.h|241| first defined here 

我試圖用簡單的情況下複製本,試圖追捕的問題,但其他情況下,我嘗試似乎工作。我不確定我在這裏做了什麼不同,會導致這個錯誤。

回答

6

這裏的問題是您的變量空間分配在頭中,然後由多個編譯單元包括 - LuaFrame.cpp.oPooledTexture.cpp.o。附註:命名您的目標文件.cpp.o令人困惑。

所以,有兩個變量名稱相同。

您需要將實際的空間分配(不是聲明,而是分配它的位)移動到cpp文件中,而不是標頭,然後將該文件與其他應用程序一起構建。是的,你現在把它放在標題中:將它設置爲NULL的位!

編輯:當你這樣做時,頭部將不再有足夠的信息來創建模板的實例,所以你將不得不顯式實例化你想使用它的每種類型的類。

+0

這似乎已經做到了。儘管我仍然感到困惑......我沒有將它放在示例中,因爲它看起來並不相關,但是類中還有另一個靜態變量(用於存儲各種資源的哈希表)。它在類的塊中以幾乎相同的方式聲明。我認爲這應該是因爲成爲模板班。如果我將該部分放入cpp文件中,出於某種原因必須在標題中出現錯誤。是什麼讓他們不同? (我編輯了我的問題以顯示其他變量) – Alex 2012-01-31 05:51:44

+0

(哦,它的價值,我沒有命名目標文件,這正是CMake自己命名的) – Alex 2012-01-31 05:52:02

+0

@Alex你沒有給出' ResourceTable'兩個不同的值。 – Borealid 2012-01-31 05:56:27