shared_ptr需要完整的类型;不能用lua_State *

时间:2010-03-12 15:17:52

标签: c++ boost lua shared-ptr

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

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

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

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

我可以解决这个问题吗?谢谢。

3 个答案:

答案 0 :(得分:4)

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

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

但是,如果您传递自己的删除器,则适用您自己的删除器的要求。 p完成后,请务必定义CustomDeleter

答案 1 :(得分: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;
}

答案 2 :(得分:0)

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

您似乎想要的行为是浅层复制 - 最好的方法是让LuaState不可复制并管理lua_State的生命周期,然后您可以将状态作为{传递{1}}。