gpt4 book ai didi

使用 "get"方法的 C++ 类继承

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:18:24 24 4
gpt4 key购买 nike

我想创建一个主要包含静态成员/方法的基类,例如:

class LuaObject {
public:
static const luaL_Reg Methods[];

static int Create(lua_State *L);

static LuaObject* get(lua_State *L, int pos) {
return *(LuaObject**)luaL_checkudata(L, pos, LuaObject::Metatable);
}
};

然后针对特定类型的对象从中派生:

class Pulse: public LuaObject {
public:
int n;
//...
};

const luaL_Reg Pulse::Methods[] = {
//...
};

static int Pulse::Create(lua_State *L) {
Pulse **ud = (Pulse**)lua_newuserdata(L, sizeof(Pulse*));
*ud = new Pulse();
//...
}

但是,如果不进行大量复制和粘贴(违背 LuaObject 的目的),我不确定如何解决这个问题。出现两个问题:

  1. 我收到如下错误:error: ISO C++ does not permit 'LuaObject::Methods' to be defined as 'Pulse::Methods' [-fpermissive]错误:没有在类“Pulse”中声明“int Pulse::Create(lua_State*)”成员函数。也就是说,Pulse 似乎没有从 LuaObject 继承静态成员/方法。

  2. get(L, n) 方法旨在返回指向类实例的指针,例如我希望能够写:

    Pulse *p = Pulse::get(L,1);printf("p->n = %d\n", p->n);

    However, it seems like since get is only defined for LuaObject, I'd get a LuaObject*, not a Pulse*.

How can I address these issues without having to copy Methods, Create, get etc into Pulse (and all other classes derived from LuaObject)?
I thought turning it into a template might help:

template <class T>
class LuaObject {
public:
static const luaL_Reg Methods[];

static int Create(lua_State *L);

static T* get(lua_State *L, int pos) {
return *(T**)luaL_checkudata(L, pos, T::Metatable);
}
};

class Pulse: public LuaObject<Pulse> {
public:
//...
};

但即使这样也会出现同样的错误,所以我很困惑。

编辑:根据要求,一个最小的示例程序,包括编译错误:(使用 g++ test.cpp -Llua -Lpulse -o test 构建)

#include <stdio.h>
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <pulse/pulseaudio.h>

class LuaObject {
public:
static const char *Metatable;
static const luaL_Reg Methods[];

static void InitModule(lua_State *L);
static int Create(lua_State *L);

//Retrieve object instance from Lua stack at specified position
static LuaObject* get(lua_State *L, int pos) {
return *(LuaObject**)luaL_checkudata(L, pos, LuaObject::Metatable);
}
};


class Pulse: public LuaObject {
//Here I want to avoid having to declare/define Metatable, get() etc again.
public:
static int getEvent(lua_State *L);
pa_context *ctx;
};



const char *Pulse::Metatable = "pulse"; //error: ISO C++ does not permit ‘LuaObject::Metatable’ to be defined as ‘Pulse::Metatable’ [-fpermissive]
const luaL_Reg Pulse::Methods[] = { //error: ISO C++ does not permit ‘LuaObject::Methods’ to be defined as ‘Pulse::Methods’ [-fpermissive]
{"getEvent", Pulse::getEvent},
{NULL, NULL}
};


//Set up the "pulse" module in a Lua state
static void Pulse::InitModule(lua_State *L) { //error: no ‘void Pulse::InitModule(lua_State*)’ member function declared in class ‘Pulse’
if(luaL_newmetatable(L, Pulse::Metatable)) {
luaL_setfuncs(L, Pulse::Methods, 0);
}
lua_pop(L, 1); //remove metatable from Lua stack, leave in Lua registry

static luaL_Reg lib[] = {
{"new", Pulse::Create},
{NULL, NULL}
};
luaL_newlibtable(L, lib);
lua_setglobal(L, "pulse");
}

//Called from Lua (as pulse.new()) to create a Pulse object
static int Pulse::Create(lua_State *L) { //error: no ‘int Pulse::Create(lua_State*)’ member function declared in class ‘Pulse’
Pulse **ud = (Pulse**)lua_newuserdata(L, sizeof(Pulse*));
*ud = new Pulse();
return 1;
}


//Called from Lua (as myPulse:getEvent()) to read events
int Pulse::getEvent(lua_State *L) {
//We only have L as parameter; the Pulse object is on the Lua stack,
//so we need to read it using luaL_checkudata() (which is handled
//by get())
Pulse *self = Pulse::get(L, 1); //error: invalid conversion from ‘LuaObject*’ to ‘Pulse*’ [-fpermissive]

//pretend get_pulse_event() is defined in pulseaudio.h (the actual mechanism
//is much more complex and wouldn't help the example)
int event = get_pulse_event(self->ctx);
lua_pushinteger(L, event);
return 1;
}


int main(int argc, char **argv) {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
Pulse::InitModule(L);
return luaL_dofile(L, "main.lua");
}

最佳答案

必须为 base 定义来自 base 的静态成员。如果你想为派生类定义它们,你必须再次声明它们。这并不意味着您无法访问派生的静态成员,尽管您必须知道不能将静态成员声明为 virtual

顺便说一句:static 只能在类定义中指定。

关于使用 "get"方法的 C++ 类继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30146681/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com