【发布时间】:2011-06-12 21:06:52
【问题描述】:
我曾经想过我可以在 lua 中重写一个类方法,这样当我在 C++ 中调用该函数时,它就会执行在 lua 中重写的操作。我的意思是,像这样:
C++ 类
class Person {
public:
Person(); // ctr
virtual void shout(); // Meant to be overriden
};
假设我将该类绑定到 lua,以便在 lua 中使用该对象:
--Lua code
p = Person:new()
p:shout()
我想要实现的是这样的:
Lua 文件
--luafile.lua
p = Person:new() --instantiate
--override shout()
p.shout = function(self) print("OVERRIDEN!") end
C++ 代码
int main() {
lua_State* l = lua_open();
luaL_loadlibs(l);
bind_person_class(l);
luaL_dofile("luafile.lua");
Person* p = (Person*) get_userdata_in_global(l, "p"); // get the created person in lua
p->shout(); // expecting "OVERRIDEN" to be printed on screen
lua_close(l);
return 0;
}
在上面的代码中,您可以看到我试图在 lua 中覆盖 Person 的方法,并期望从 c++ 调用被覆盖的方法。但是,当我尝试它时,不会执行覆盖的方法。我想要实现的是在 C++ 中执行覆盖的方法。你是如何做到这一点的?
====================
我想了一种方法来实现这一点,但我不确定这是否好。我的想法是导出的类应该有一个字符串,表示 lua 中的全局变量名称,用于保存此类的实例。像这样:
class Person {
public:
Person();
string luaVarName; // lua's global variable to hold this class
virtual void shout() {
luaL_dostring(luaVarName + ":shoutScript()"); // now shout will call shoutScript() in lua
}
};
因此,在lua中,对象负责实现shoutScript()并将全局变量分配给对象:
--LUA
p = Person:new()
p.shoutScript = function(self) print("OVERRIDEN") end
p.luaVarName = "p"
使用上面的代码,我可以实现我想要的(虽然还没有测试过)。但是,还有其他合适的方法来实现我想要的吗?
【问题讨论】:
-
你明白为什么第一个变体失败了吗?
-
@GMan:我想是因为我还没有真正重写该方法。 AFAIK,当您在 C++ 中调用方法(或函数)时,您指的是指令所在的地址。当一个函数被覆盖时,有一种机制可以引用另一个地址。因此,当我在 LUA 中“覆盖”它时,C++ 并不知道它,因此调用了真正的函数。 CMIIW。
标签: c++ class methods lua overriding