shared_ptr需要完整类型;不能与lua_State*一起使用。

我正在为 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)

有什么解决方法吗?谢谢。

原文链接 https://stackoverflow.com/questions/2433667

点赞
stackoverflow用户34509
stackoverflow用户34509

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

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

但是,如果您传递自己的删除器,则会应用自己删除器的要求。请务必在lua_State已经完成后定义CustomDeleter

2010-03-12 15:55:49
stackoverflow用户36565
stackoverflow用户36565

看起来 boost::shared_ptr 要求在实例化时需要一个完整的类型似乎有些奇怪,因此我写了这个小测试来证明相反的结果(代码在最后)。

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

也许你的意思是?:

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

证明 boost::shared_ptr 不需要完整类型:

// 前向声明
struct test;
test * create();
void destroy(test *);

// 与问题中的包装器相等的包装器
struct wrapper {
   boost::shared_ptr<test> sp;
   wrapper() : sp( create(), destroy ) {}
};

// 实际定义
struct test {};
test * create() { return new test; }
void destroy(test *t) { delete t; }

// 使其可执行
int main() {
   test t;
}
2010-03-12 16:14:38
stackoverflow用户59379
stackoverflow用户59379

考虑到无法克隆 lua_State*,复制 LuaState 对象是否有意义?复制这样一个不可复制的对象的预期语义是什么?

你似乎想要的行为是 _浅复制_,最好的方法是让 LuaState 无法复制,并管理 lua_State 的生命周期,然后你可以将该状态作为 shared_ptr<LuaState> 传递。

2010-03-12 16:20:54