我有一个名为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
我尝试用一个更简单的案例来重现这一点,试图找出问题,但我尝试的其他情况似乎有用。我不确定我在这里做的不同会导致这个错误。
答案 0 :(得分:6)
这里的问题是变量的空间是在标题中分配的,然后由多个编译单元 - LuaFrame.cpp.o
和PooledTexture.cpp.o
包含。附注:命名对象文件.cpp.o
令人困惑。
因此,有两个同名的变量。
您需要将实际空间分配(不是声明,而是分配它的位)移动到cpp
文件而不是标头,然后将其与应用程序的其余部分一起构建。是的,你现在在标题中有它:你将它设置为NULL
的位!