C++ で、構造のようなバイナリ ツリーを作成するクラスがあり、それを次のように使用するとします。
CTreeRoot* root = new CTreeRoot(/* whatever */);
CNode* leftNode = root->getLeftNode();
CNode* rightNode = root->getRightNOde();
leftNode->doSomething();
rightNode->doSomething();
// etc
また、左右のノードには独自の左右のノードがあるとします (したがって、バイナリ ツリー)。これを Lua に公開して ( luabind を使用せずに)、同じようなことができるようにします。
local root = treeroot.new(/* whatever */)
local left = root:getLeftNode()
local right = root:getRightNode()
left:doSomething();
right:doSomething();
私はそれのほとんどを機能させました。ただし、getLeftNode() および getRightNode() メソッドについては、「間違っている」と確信しています。たとえば、C++で getLeftNode() を実装する方法は次のとおりです。
int MyLua::TreeRootGetLeftNode(luaState* L)
{
CTreeRoot* root = (CTreeRoot*)luaL_checkudata(L, 1, "MyLua.treeroot");
CNode* leftNode = root->getLeftNode();
if (leftNode != NULL)
{
int size = sizeof(CNode);
// create a new copy of the CNode object inplace of the memory Lua
// allocated for us
new ((CNode*)lua_newuserdata(L,size)) CNode((const CNode&)*leftNode);
lua_setmetatable(L, "MyLua.treenode");
}
else
{
lua_pushnil(L);
}
return 1;
}
ユーザーデータを CTreeRoot オブジェクトにキャストし、getLeftNode() を呼び出し、それが存在することを確認してから (これが「間違った部分」です)、返すオブジェクトをコピーするコピー コンストラクターを使用して別のユーザーデータ データ オブジェクトを作成します。
これは、このタイプのシナリオの「標準的な方法」ですか? 本当に必要なのは既存のオブジェクトへの参照だけなので、オブジェクトの別のコピーを作成することは避けたいと思われます。
新しいオブジェクトを作成したくないので、これは lightuserdata に最適な場所のように思えます。既に存在するオブジェクトを返すことができれば幸いです。ただし、問題は、lightuserdata にはメタ テーブルがないため、オブジェクトを元に戻すと、オブジェクトが役に立たなくなることです。基本的に、私は次のようなことをしたい:
int MyLua::TreeRootGetLeftNode(luaState* L)
{
CTreeRoot* root = (CTreeRoot*)luaL_checkudata(L, 1, "MyLua.treeroot");
CNode* leftNode = root->getLeftNode();
if (leftNode != NULL)
{
// "WRONG" CODE BUT SHOWS WHAT I WISH I COULD DO
lua_pushlightuserdata(L, (void*)leftNode);
lua_setmetatable(L, "MyLua.treenode");
}
else
{
lua_pushnil(L);
}
return 1;
}
MyLua::TreeRootGetLeftNode
Lua でオブジェクトを「オブジェクト」として使用できるように、すでに存在するオブジェクトのコピーをメソッドで Lua に返す方法を教えてください。