我正在为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)
我可以解决这个问题吗?谢谢。
答案 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}}。