2010-06-23 213 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); 
}