2012-07-11 120 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