2012-07-11 115 views
0

对不起,如果这有点复杂。我已经采取了对象,并删除了一切多余的东西来缩小错误的原因。这是什么导致我的错误:从静态成员链接错误

d3d11module.h

#ifndef STUFF_H 
#define STUFF_H 

#include <map> 
#include <string> 
#include <memory> 

class D3D11 
{ 
public: 
    class Shader; 
    template<class T> 
    class ShaderRegister; 

    typedef std::map<std::string, std::shared_ptr<Shader>(*)()> SHADER_CREATE_MAP; 

private: 
    static SHADER_CREATE_MAP createMap; 
}; 

class D3D11::Shader 
{ 

}; 

template<class T> 
std::shared_ptr<D3D11::Shader> createShader() {return std::shared_ptr<D3D11::Shader>(new T);} 

template<class T> 
class D3D11::ShaderRegister 
{ 
public: 
    ShaderRegister(std::string const & s) 
    { 
     D3D11::createMap.insert(std::pair<std::string,std::shared_ptr<Shader>(*)()>(s, &createShader<T>)); 
    } 
}; 

#endif 

只是这一切真正的简单说明。有一个名为d3d11的类包含几个类。首先是类能够派生和实现的着色器类,但在这里留下空白,因为它的内容与问题无关。那么我有一个字符串索引的映射,对应于函数指针。

ShaderRegister对象将成为派生着色器类中的静态私有成员。然后在外面,调用构造函数,以便指定索引和指向createShader()的指针存储在该索引处。通过这样做,调用索引将调用此模板化函数,并返回该派生着色器的实例。

虽然尝试派生着色器对象并创建ShaderRegister实例并尝试调用其构造函数,但我得到链接错误。看看:

#ifndef DIFFUSE_SHADER 
#define DIFFUSE_SHADER 

#include "d3d11module.h" 

class DiffuseShader : public D3D11::Shader 
{ 
    static D3D11::ShaderRegister<DiffuseShader> reg; 
}; 

D3D11::ShaderRegister<DiffuseShader> DiffuseShader::reg("DiffuseShader"); 

#endif 

这样做会导致一个相当痛苦的看链接错误。

main.obj : error LNK2001: unresolved external symbol "private: static class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::tr1::shared_ptr<class D3D11::Shader> (__cdecl*)(void),struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class std::tr1::shared_ptr<class D3D11::Shader> (__cdecl*)(void)> > > D3D11::createMap" ([email protected]@@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@[email protected]@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@[email protected][email protected][email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@[email protected]@[email protected]@@@[email protected]@[email protected]@A)

的是,在某些时候使用时,我认为这是想说的是在D3D11类的静态地图对象不确定。但我认为静态对象是在程序开始时构建的。发生什么了?

回答

4

静态成员在类中声明就像所有其他东西一样,但它们也必须在一个且唯一的一个源文件(.cpp)中定义。这与声明一个成员函数原型相同,然后在其他地方定义该函数的主体。

SHADER_CREATE_MAP D3D11::createMap; 
+0

哇,我想某处我在我的脑海里得知静态成员被定义为隐含。在使用C++时,这种想法不是很友好:P。它会让我接受答案 – FatalCatharsis 2012-07-11 02:57:01