我相信你們中的一些人可能會遇到這個問題。我有一個用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