我相信你们中的一些人可能会遇到这个问题。我有一个用C++编写的叫做矩阵的用户数据对象,通常使用运算符重载方式,比如。lua userdata按值传递
CMatrix<T>& operator=(const CMatrix<T>& b);
CMatrix<T>& operator=(const T& rhs);
在C++中,当我创建两个矩阵说A
和B
和使A=B
则A和B可被用作两个独立的对象。然而,在Lua写A=B
并更改B
的任何属性时,A
也会发生变化。
从Lua手册中可以看出,据说Lua通过引用来解释上述行为来做userdata的分配。但是,如何使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变量的引用。我不确定这是否真的有效,如果值得在性能方面付出努力。
你最后的部分是严格的C++问题;你在谈论什么叫做“写时复制”语义。除非你的矩阵对象很大,否则对于一个值类型通常是一个糟糕的主意。当然,它听起来很快。但随着现代移动语义和复制elision,你会发现自己没有做太多的对象复制。它也使得你的对象非线程安全,或者需要你锁定互斥锁来访问它们。 –
“如何让A = B按值传递,以便在B发生变化时A不受影响。” - 这就像问:“我怎样才能让MyClass c = new MyClass();'在C++中工作,就像它在Java中一样?” - 即使你可以(而且我认为你不能),这不是一个好主意。 – immibis
我只是有一个方法克隆它的矩阵。 – warspyking