Shared_ptr erfordert eine vollständigen Typen; kann es nicht mit lua_State verwenden *

StackOverflow https://stackoverflow.com/questions/2433667

  •  19-09-2019
  •  | 
  •  

Frage

Ich schreibe einen C ++ / OOP-Wrapper für Lua. Mein Code ist:

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

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

Das Problem ist lua_State ist unvollständig eingeben und shared_ptr Konstruktor erfordert eine vollständigen Typen. Und ich brauche sicheren Zeiger-Sharing. (Komisch Boost-docs sagen, die meisten Funktionen benötigen keinen vollständigen Typen, aber Konstruktor erfordert, so gibt es keine Möglichkeit, es zu verwenden. http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/smart_ptr.htm )

Can kann ich dieses Problem lösen? Danke.

War es hilfreich?

Lösung

Sie sind mit Ihrem eigenen deleter, was bedeutet, dass Sie müssen keine vollständigen Typen auf Konstruktion haben. Die einzige Voraussetzung ist, dass CustomDeleter damit umgehen kann. (Es kann den Zeiger umwandeln zu einem vollständigen Typ übergeben, zum Beispiel (etwa von void* zu CompleteType*).

Der Hintergrund der Vollständigkeit ist, dass wenn der Konstruktor von shared_ptr mit dem Standard deleter aufgerufen wird, wird es eine Klasse instanziiert, die die Linie delete p; enthält - und dieser Code korrekt sein, p darf nicht unvollständig sein. Der Destruktor wird diese deleter Code aufrufen indirekt, so dass es nicht auf die Vollständigkeit der Art abhängig ist.

Allerdings, wenn Sie Ihre eigenen deleter passieren, werden die Anforderungen der eigenen deleter gelten. Achten Sie darauf, definieren CustomDeleter nach lua_State abgeschlossen sein.

Andere Tipps

Es schien seltsam, dass boost::shared_ptr einen vollständigen Typen für Instanziierung erfordern würde, so dass ich diesen kleinen kleinen Test geschrieben, die das Gegenteil (Code am Ende) zeigen.

Ich glaube, dass das Problem nicht mit dem Typ ist, um vollständig zu sein, aber mit dem zweiten Argumente, dass Sie an dem shared_ptr Konstruktor sind vorbei, das sieht aus wie eine Member-Funktion. Das zweite Argument ist etwas aufrufbar mit einem einzigen Zeiger Argumente sein. Wenn Sie eine Elementfunktion Ihrer Wrapper verwenden möchten, können Sie boost::bind verwenden, um die Schnittstelle anpassen.

Vielleicht meinte Sie:

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

Demonstration, dass boost::shared_ptr nicht vollständig Typen benötigt:

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

Da ein lua_State * kann nicht geklont werden, ist das Kopieren eines LuaState Objekt sinnvoll? Was sind die erwarteten Semantik des Kopierens eine solche von Natur aus nicht kopierbare Objekt?

Das Verhalten, das Sie scheinen zu wollen, ist Kopieren flach - und der beste Weg, das zu tun, ist für LuaState uncopyable zu sein und die Lebensdauer des lua_State verwalten, dann können Sie den Staat als shared_ptr<LuaState> passieren um .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top