Domanda

Sto scrivendo un wrapper C ++ / OOP per Lua. Il mio codice è:

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

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

Il problema è lua_State è tipo incompleto e costruttore shared_ptr richiede tipo completo. E ho bisogno di sicurezza condivisione puntatore. (La cosa divertente docs spinta dicono la maggior parte delle funzioni non necessitano di tipo completo, ma il costruttore richiede, quindi non c'è modo di utilizzarlo. http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/smart_ptr.htm )

Posso posso risolvere questo problema? Grazie.

È stato utile?

Soluzione

Si sta utilizzando il proprio deleter, il che significa che non c'è bisogno di avere un tipo completo su di costruzione. L'unico requisito è che CustomDeleter in grado di gestire questo. (Si può convertire il puntatore passato a un tipo completo, per esempio (per esempio, da void* a CompleteType*).

Lo sfondo di completezza è che una volta che il costruttore di shared_ptr viene chiamato con il deleter di default, sarà istanziare una classe che contiene la linea di delete p; - e per questo codice sia corretta, p non deve essere incompleta. Il distruttore chiamerà questo codice deleter indirettamente, in modo da non dipendere la completezza del tipo.

Tuttavia, se si passa il proprio deleter, si applicano i requisiti del proprio deleter. Assicurati di definire CustomDeleter dopo lua_State è diventato completata.

Altri suggerimenti

Mi sembrava strano che boost::shared_ptr richiederebbe un tipo completo per esemplificazione, così ho scritto questo piccolo test poco che dimostrano la (codice alla fine) opposta.

Credo che il problema non è con il tipo di bisogno di essere completa, ma con il secondo argomento che si sta passando al costruttore shared_ptr, che assomiglia a una funzione membro. Il secondo argomento deve essere qualcosa richiamabile con un singolo argomento puntatore. Se si desidera utilizzare una funzione membro della vostra involucro è possibile utilizzare boost::bind per adattare l'interfaccia.

Forse volevi dire:?

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

Dimostrazione che boost::shared_ptr non richiede tipi completi:

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

Dato che un lua_State * non può essere clonato, è la copia di un oggetto LuaState significativo? Quali sono la semantica attesi di copia di un oggetto come intrinsecamente uncopyable?

Il comportamento sembrate desiderare è superficiale copia - e il modo migliore per farlo è per LuaState essere uncopyable e gestire la durata della lua_State allora si può passare tutto lo stato come un shared_ptr<LuaState> .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top