如何为__index指向函数的Lua类实现继承?
问题根因
你遇到的问题本质是Lua的__index元方法触发规则和预期不一致:
当访问表中不存在的键时,如果__index指向函数,Lua只会直接执行该函数并返回它的返回值,不会自动对该函数本身或者返回结果做进一步的元表查找。
你给DerivedClass这个C函数设置元表的操作不会生效,因为Lua在DerivedClass返回nil之后就直接终止查找流程了,不会主动去查询DerivedClass自身元表的__index指向的BaseClass。
解决方案
最直接的实现方式是在派生类的__index函数中手动实现基类 fallback 逻辑:
你需要修改DerivedClass函数的实现,当自身没有匹配到对应键时,主动调用基类的查询函数透传参数,返回基类的查询结果。
修改后的DerivedClass示例代码如下:
int DerivedClass( lua_State* lua ) { juce::Logger::writeToLog( "DerivedClass called" ); const char* key = lua_tostring( lua, 2 ); // 先处理派生类独有的方法 if ( strcmp( key, "derived_specific_method" ) == 0 ) { // 这里压入派生类独有方法的C函数即可 // lua_pushcfunction(lua, Derived_specific_method); // return 1; } // 自身没有匹配到,透传参数调用基类查询函数 lua_getglobal( lua, "BaseClass" ); lua_pushvalue( lua, 1 ); // 透传实例对象参数 lua_pushvalue( lua, 2 ); // 透传要查询的key参数 lua_call( lua, 2, 1 ); return 1; }
同时你原来给DerivedClass函数设置元表的代码是无效的,可以直接删除。
执行流程验证
修改后执行obj:foo()的流程为:
obj表中没有foo键,触发元表__index指向的DerivedClass函数DerivedClass没有匹配到foo键,主动调用BaseClass函数透传参数BaseClass匹配到foo键,返回对应的C函数BaseClass_foo- Lua执行返回的C函数,正常输出日志,不会报错。
如果需要实现多层继承,只需要在每一层的类查询函数中都加上对应父类的 fallback 逻辑即可,也可以封装通用的继承链查询工具函数,减少重复代码。
内容的提问来源于stack exchange,提问作者jiandingzhe
相关产品推荐
相关产品推荐

