模板类的静态变量的多个定义

时间:2012-01-31 05:35:59

标签: c++ templates static-variables

我有一个名为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

我尝试用一​​个更简单的案例来重现这一点,试图找出问题,但我尝试的其他情况似乎有用。我不确定我在这里做的不同会导致这个错误。

1 个答案:

答案 0 :(得分:6)

这里的问题是变量的空间是在标题中分配的,然后由多个编译单元 - LuaFrame.cpp.oPooledTexture.cpp.o包含。附注:命名对象文件.cpp.o令人困惑。

因此,有两个同名的变量。

您需要将实际空间分配(不是声明,而是分配它的位)移动到cpp文件而不是标头,然后将其与应用程序的其余部分一起构建。是的,你现在在标题中有它:你将它设置为NULL的位!

编辑:执行此操作时,标题将不再具有足够的信息来创建模板的实例,因此您必须为您希望使用它的每种类型显式实例化类。