8

我正在为 Lua 编写一个 C++/OOP 包装器。我的代码是:

class LuaState
{
     boost::shared_ptr<lua_State> L;

     LuaState(): L( luaL_newstate(), LuaState::CustomDeleter )
     {
     }
}

问题是 lua_State 是不完整的类型,而 shared_ptr 构造函数需要完整的类型。我需要安全的指针共享。(有趣的是 boost 文档说大多数函数不需要完整的类型,但构造函数需要,所以没有办法使用它。http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/smart_ptr.htm )

我能解决这个问题吗?谢谢你。

4

3 回答 3

4

您正在使用自己的删除器,这意味着您不必在构造时拥有完整的类型。唯一的要求是CustomDeleter可以处理。(它可以将传递的指针转换为完整的类型,例如(例如,从void*to CompleteType*)。

完整性的背景是,一旦shared_ptr使用默认删除器调用 的构造函数,它将实例化包含该行的类delete p;- 并且要使此代码正确,p一定不能不完整。析构函数会间接调用这个删除代码,所以它不依赖于类型的完整性。

但是,如果您通过自己的删除器,则将适用您自己的删除器的要求。请务必在完成CustomDeleter后定义lua_State

于 2010-03-12T15:55:49.943 回答
1

需要一个完整的类型进行实例化似乎很奇怪boost::shared_ptr,所以我编写了这个小测试来演示相反的情况(最后的代码)。

我认为问题不在于需要完整的类型,而在于您传递给shared_ptr构造函数的第二个参数,它看起来像一个成员函数。第二个参数必须是可以使用单个指针参数调用的东西。如果要使用包装器的成员函数,可以使用boost::bind来调整接口。

也许你的意思是?:

 LuaState(): L( luaL_newstate(), boost::bind(LuaState::CustomDeleter,this,_1) )
 {
 }

boost::shared_ptr不需要完整类型的演示:

// forward declarations
struct test;
test * create();
void destroy(test *);

// wrapper equivalent to the one in the question
struct wrapper {
   boost::shared_ptr<test> sp;
   wrapper() : sp( create(), destroy ) {}
};

// actual definitions
struct test {};
test * create() { return new test; }
void destroy(test *t) { delete t; }

// make it executable
int main() {
   test t;
}
于 2010-03-12T16:14:38.670 回答
0

鉴于无法克隆 lua_State*,复制 LuaState 对象有意义吗?复制这种固有的不可复制对象的预期语义是什么?

您似乎想要的行为是浅复制- 最好的方法是让 LuaState 不可复制并管理 lua_State 的生命周期,然后您可以将状态作为shared_ptr<LuaState>.

于 2010-03-12T16:20:54.873 回答