2010-06-23 122 views
0

我試圖設置一些與Lua的東西,但具體的Lua對我的問題並不重要。繼承和存儲靜態類信息

我希望能夠做的就是調用一個函數,比如說OpenLib<T>(L),並讓它獲取特定類的表名(以及它的表)並將它註冊到Lua中。它基本上歸結爲:

template <class T> 
static void OpenLib(lua_State* L) 
{ 
    // this func does some other stuff too that I'm omitting, important bit below 
    if (T::myTable && T::myTableName) 
    { 
     luaL_openlib(L, T::myTableName, T::myTable, 0); 
    } 
} 

我試過這幾種不同的方式,我不能讓它正常工作。我試圖使包含myTable的和myTableName像這樣一個基類:

class LuaInfo 
{ 
public: 
    static const char* myTableName; 
    static luaL_reg* myTable; 
} 

然後我再從LuaInfo繼承,然後在我所需要的信息填寫。沒有工作,因爲從LuaInfo繼承的所有類將得到相同的信息,所以我環顧四周,有這樣的想法:

template <class t> 
class LuaInfo 
// ... 

這使得該語法現在來初始化它有點傻,因爲我必須做類Widget:public LuaInfo,但它更接近工作。

template <class T> 
void OpenLib(lua_State* L) 
{ 
    if (T::myTable && T::myTableName) 
    { 
     luaL_openlib(L, LuaInfo<T>::myTableName, LuaInfo<T>::myTable, 0); 
    } 
} 

我試過的這幾個變種,試圖得到正確的,但我不斷收到這樣的錯誤

undefined reference to `ag::LuaInfo<ag::ui::Widget>::myTable' 

就是我想要做的可能,如果是這樣,什麼權怎麼去做呢?

回答

1

使用

template<typename T> 
class LuaInfo 
{ 
    static const char* myTableName; 
    static lua_reg* myTable; 
}; 

應該工作正常。

你的問題是你需要定義你的靜態變量。

包含一堆這樣的線將解決它

luaL_reg* LuaInfo<ag::ui::Widget>::myTable = 0; 
const char * LuaInfo<ag::ui::Widget>::myTableName = 0; 

luaL_reg* LuaInfo<ag::ui::OtherClass>::myTable = 0; 
const char * LuaInfo<ag::ui::OtherClass>::myTableName = 0; 

等一個源文件。

你可能想要定義一個宏來使這個更好。

#define LUAINFOIMPL(X) luaL_reg* LuaInfo<X>::myTable=0; const char * LuaInfo<X>::myTableName=0 
LUAINFOIMPL(ag::ui::Widget); 
LUAINFOIMPL(ag::ui::OtherClass); 

然而,它的規模有點難以衡量。我以爲特質風格模板可能會解決這個問題..但我不確定它們的規模會更好。

0

您的第一次嘗試對我來說工作得很好。我想你只是忘了初始化靜態成員,並得到了一些鏈接錯誤。這是我做過什麼:

template <class T> 
static void OpenLib(lua_State* L) 
{ 
    // this func does some other stuff too that I'm omitting, important bit below 
    if (T::myTable && T::myTableName) 
    { 
     luaL_openlib(L, T::myTableName, T::myTable, 0); 
    } 
} 

class LuaInfo 
{ 
    public: 
     static const char* myTableName; 
     static luaL_reg* myTable; 
}; 

//init static members 
const char* LuaInfo::myTableName = 0; 
luaL_reg* LuaInfo::myTable = 0; 

int main() 
{ 
    OpenLib<LuaInfo>(0); 
} 

現在,如果你想給其他相關資訊,OpenLib你必須創建一個像LuaInfo一個新的類,並給新的類作爲模板參數。

但是,您爲什麼要將此信息作爲模板參數?國際海事組織,這是更簡單:

struct LuaInfo 
{ 
    const char* myTableName; 
    luaL_reg* myTable; 
}; 

static void OpenLib(lua_State* L, LuaInfo info) 
{ 
    // this func does some other stuff too that I'm omitting, important bit below 
    if (info.myTable && info.myTableName) 
    { 
     luaL_openlib(L, info.myTableName, info.myTable, 0); 
    } 
} 

int main() 
{ 
    LuaInfo info = {/*some values here*/}; 
    OpenLib(0, info); 
}