gpt4 book ai didi

c++ - lua userdata 按值传递

转载 作者:搜寻专家 更新时间:2023-10-31 00:58:35 29 4
gpt4 key购买 nike

我相信你们中的一些人可能会遇到这个问题。我有一个用 C++ 编写的名为矩阵的用户数据对象,使用常用的运算符重载方式,例如。

CMatrix<T>& operator=(const CMatrix<T>& b);
CMatrix<T>& operator=(const T& rhs);

在 C++ 中,当我创建两个矩阵时说 AB 并使 A=B 然后 A 和 B 可以用作两个独立的对象。但是,在 Lua 中,当我编写 A=B 并更改 B 的任何属性时,A 也会更改。

很明显,从 Lua 手册中也可以看出,Lua 通过引用分配用户数据,这解释了上述行为。但是,我怎样才能使 A=B 按值传递,以便当 B 更改时 A 不受影响。

事实上,我想让赋值 A=B 通过引用传递,这确实非常快,Matlab 也这样做,但是当我设置 B< 的属性时 第一次,我希望独立创建 B,这是在我的 Matlab 中实践的,因为我可以从 Matlab 的内存使用情况中跟踪。

如果这是可能的,它是在 C++ 中还是在 lua 包装器代码中的某个地方完成的?任何示例代码都会很棒。

编辑 1:这是我的想法,我不确定它是否会起作用或者是否足够快

typedef struct luaelement
{
int type;
std::string name;
void* addr; //newly added field
bool isRef; //newly added
} luaelement;

glbLuaElementSet=new set<luaelement,comparenocaseforluaelement>();

int l_newindex(lua_State* L)
{
luaelement element;
const char* key=lua_tostring(L,-2);
string str=key;
element.name=key;
element.type=lua_type(L,-1);
//How can I get the address, maybe a metamethod named address
glbLuaElementSet->insert(element);
lua_rawset(L,1);
}

void l_registermetamethod(lua_State* L)
{
lua_getglobal(L,"_G");
lua_createtable(L, 0, 1);
lua_pushcfunction(L, l_newindex);
lua_setfield(L, -2, "__newindex");
lua_setmetatable(L, -2);
}

现在有了 glbLuaElementSet 变量和 l_newindex 元方法,我可以跟踪插入到全局 _G 表中的所有变量。我计划通过检查 void* 地址来实现并查看是否存在对现有 userdata 变量的任何引用。我不确定这是否真的有效,以及在性能方面是否值得付出努力。

最佳答案

However, how can I make A=B to pass by value so that when B changes A is not affected.

你不能。

记住:Lua 是动态类型。因此,虽然 AB 恰好现在存储了您的矩阵类型,但以后再去 A = 1 就完全没问题了。现在,A 存储一个整数。

C++ 和 Lua 是非常不同的语言。在 C++ 中,变量要么是对象,要么是对对象的引用(指针是指针类型的对象)。每个变量只会保存它开头的对象。存储在该对象中的值可以更改,但对象本身存在并且具有由相关变量的生命周期定义的生命周期。

在 Lua 中,变量只是一个可以存储对象的盒子。那个盒子与它当前恰好存储的对象没有关系;任何盒子都可以容纳任何物体。在任何时候,您都可以将那个盒子里的东西与任何其他盒子里的东西交换。

您不能干涉将一个变量复制到另一个变量(通常。您可以进行元表体操,但这只适用于该表的成员。局部变量永远不会受到影响)。这就是 Lua 作为一种语言的工作方式。 C++ 变量是对象; Lua变量是储物箱。最好接受你不能在 Lua 中编写 C++ 风格的代码,而是专注于在 Lua 中编写 Lua 风格的代码。

因此,如果您想创建对象的拷贝,则必须显式创建该对象的拷贝。


Here is my idea, I am not sure if it will work at all or if so fast enough

由于多种原因,它不会工作。

首先,您要将元表应用于全局表本身,这通常是……粗鲁的。

其次,即使您的代码有效,它也不适用于像这样简单的事情:

globalVar = {}  --Perfectly legal to set a table inside the global table.
globalVar.value = A
globalVar.value = B --Will not alert your copying code.

__newindex 元方法不是递归。它不能在表的层次结构中上下移动。因此存储在全局表中的表仍然可以更改其成员。

停止尝试将 Lua 变成它不是的东西。使用您拥有的语言,而不是您想要的语言。

关于c++ - lua userdata 按值传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35214952/

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