【发布时间】:2016-02-05 01:43:21
【问题描述】:
我相信你们中的一些人可能会遇到这个问题。我有一个名为矩阵的用户数据对象,它是用 C++ 编写的,具有运算符重载的常用方法,例如。
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 通过引用来分配用户数据,这解释了上述行为。但是,我怎样才能让A=B 按值传递,以便B 更改时A 不受影响。
事实上,我想让赋值A=B通过引用传递,这确实非常快并且Matlab可以做到,但是当我第一次设置B的属性时,我想要@987654333 @ 是独立创建的,这是我的 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* 地址来实施并查看是否存在对现有用户数据变量的任何引用。我不确定这是否真的有效,以及在性能方面是否值得付出努力。
【问题讨论】:
-
你的最后一部分是一个严格的 C++ 问题;你所说的被称为“写时复制”语义。除非您的矩阵对象很大,否则对于值类型通常是一个糟糕的主意。当然,它听起来很快。但是使用现代移动语义和复制省略,您会发现自己并没有做太多的对象复制。它还使您的对象非常非线程安全,或者需要您锁定互斥锁才能访问它们。
-
"如何让 A=B 按值传递,这样当 B 改变时 A 不受影响。" - 这就像问“我怎样才能让
MyClass c = new MyClass();在 C++ 中像在 Java 中一样工作?” - 即使你可以(我认为你不能),这也不是一个好主意。 -
我只需要一种方法来克隆它。
-
@warspyking:这正是我在阅读完所有 cmets 后打算做的事情。