Pregunta

Estoy escribiendo un envoltorio de C ++ / programación orientada a objetos para LUA. Mi código es:

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

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

El problema es lua_State es tipo incompleto y constructor shared_ptr requiere tipo completo. Y necesito compartir puntero del seguro. (Docs impulsar Lo curioso dicen que la mayoría de las funciones no requieren de tipo completo, pero el constructor requiere, por lo que no hay manera de utilizarlo. http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/smart_ptr.htm )

Can puedo solucionar esto? Gracias.

¿Fue útil?

Solución

Usted está utilizando su propia Deleter, lo que significa que usted no tiene que tener un tipo completo en la construcción. El único requisito es que CustomDeleter puede manejar eso. (Se puede convertir el puntero pasado a un tipo completo, por ejemplo (por ejemplo, de void* a CompleteType*).

El fondo de completitud es que una vez que el constructor de shared_ptr se llama con el Deleter defecto, se creará una instancia de una clase que contiene la línea de delete p; - y para que este código sea correcto, p no debe estar incompletos. El destructor llamará a este código Deleter indirectamente, por lo que no depende de la integridad del tipo.

Sin embargo, si usted pasa su propio Deleter, se aplicarán los requisitos de su propia Deleter. Asegúrese de definir CustomDeleter después lua_State ha convertido completado.

Otros consejos

Me pareció extraño que boost::shared_ptr requeriría un tipo completo para la creación de instancias, así que escribí esta pequeña pequeña prueba que demuestre lo contrario (código al final).

Creo que el problema no es con el tipo de necesidad de ser completa, pero con el segundo argumento que está pasando al constructor shared_ptr, que se parece a una función miembro. El segundo argumento debe ser algo exigible con un argumento único puntero. Si desea utilizar una función miembro de su envoltorio puede utilizar boost::bind para adaptar la interfaz.

Tal vez quisiste decir:?

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

Demostración de que boost::shared_ptr no requiere 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 una lua_State * no puede ser clonado, se copia un objeto LuaState significativa? ¿Cuáles son los esperados semántica de la copia de un objeto tan inherentemente incopiable?

El comportamiento parece que quieres es copia superficial - y la mejor manera de hacerlo es para LuaState sea incopiable y gestionar el tiempo de vida del lua_State entonces puede pasar de todo el estado como shared_ptr<LuaState> .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top