Pergunta

Estou escrevendo um invólucro C ++/OOP para Lua. Meu código é:

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

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

O problema é que Lua_state é tipo incompleto e o construtor shared_ptr requer tipo completo. E eu preciso de compartilhamento de ponteiro seguro. (Os documentos engraçados do Boost dizem que a maioria das funções não requer tipo completo, mas o construtor exige, portanto, não há como usá -lo. http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/smart_ptr.htm)

Posso resolver isso? Obrigada.

Foi útil?

Solução

Você está usando seu próprio Deleter, o que significa que não precisa ter um tipo completo de construção. O único requisito é que CustomDeleter pode lidar com isso. (pode converter o ponteiro que passou para um tipo completo, por exemplo (digamos, de void* para CompleteType*).

O pano de fundo da integridade é que, uma vez que o construtor de shared_ptr é chamado com o deleter padrão, ele instanciará uma classe que contém a linha delete p; - e para que este código esteja correto, p não deve estar incompleto. O destruidor chamará esse código deleter indiretamente, para que não dependa da integridade do tipo.

No entanto, se você aprovar seu próprio Deleter, os requisitos do seu próprio Deleter serão aplicados. Certifique -se de definir CustomDeleter depois lua_State foi concluído.

Outras dicas

Parecia estranho que boost::shared_ptr exigiria um tipo completo de instanciação, então escrevi este pequeno teste pequeno que demonstra o oposto (código no final).

Eu acredito que o problema não está com o tipo que precisa ser completo, mas com o segundo argumento de que você está passando para o shared_ptr construtor, que parece uma função de membro. O segundo argumento deve ser algo chamável com um único argumento de ponteiro. Se você deseja usar uma função de membro do seu invólucro, você pode usar boost::bind Para adaptar a interface.

Talvez você quis dizer?:

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

Demonstração que boost::shared_ptr não requer tipos completos:

// 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;
}

Dado que um lua_state* não pode ser clonado, copiando um objeto Luastate significativo? Quais são a semântica esperada de copiar um objeto inerentemente incomparável?

O comportamento que você parece querer é cópia superficial - e a melhor maneira de fazer isso é que o Luastate seja incomparável e gerencie a vida inteira do Lua_state, então você pode passar pelo estado como um shared_ptr<LuaState>.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top