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

Multiple definitions of a static variable of a templated class

本文关键字:定义 变量 静态      更新时间:2023-10-16

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

我试着用一个更简单的案例来重现这一点,试图找出问题所在,但我尝试的其他案例似乎奏效了。我不确定我在这里做了什么不同的事情会导致这个错误。

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

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

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

EDIT:当你这样做时,头将不再有足够的信息来创建模板的实例,所以你必须为你希望使用它的每种类型显式实例化类。