8
votes

Shared_Ptr nécessite un type complet; ne peut pas l'utiliser avec Lua_State *

J'écris un wrapper C ++ / oop pour Lua. Mon code est le suivant:

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

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


4 commentaires

Pourquoi avez-vous besoin de partage sûr du pointeur, si je peux demander? Vous ne pouvez pas simplement appeler Lual_Newstate dans le constructeur et Lua_Close dans le destructeur.


Luastate A, B; a = b; // lua_state in B ne sera jamais publié // lua_state dans A sera publié deux fois que l'autre option est clonant la structure Lua_State dans le constructeur de copie et l'opérateur =. Mais je suppose que c'est une solution lourde.


Vous ne pouvez pas cloner manuellement la structure Lua_State. Cela va exploser dans votre visage. Je l'ai essayé :)


C'est ce que je pensais. :) Qu'est-ce qu'une solution pour la gestion sûre de Lua_State *?


3 Réponses :


4
votes

Vous utilisez votre propre Delier, ce qui signifie que vous n'avez pas besoin d'avoir un type complet lors de la construction. La seule exigence est que CustomDeleter peut gérer cela. (Il peut convertir le pointeur transmis en un type complet, par exemple (disons, de Void * à completsetype * ).

L'arrière-plan de l'exhaustivité est qu'une fois que le constructeur de partagé_ptr est appelé avec le Delier par défaut, il instanciera une classe contenant la ligne Supprimer p; - et pour Ce code doit être correct, p ne doit pas être incomplet. Le destructeur appellera ce code de Delier indirectement, donc cela ne dépendra pas de l'exhaustivité du type.

Cependant, si vous passez votre propre Delier, les exigences de votre propre Delier s'appliqueront. Assurez-vous de définir CustomDeleter après Lua_State est devenu terminé.


2 commentaires

Merci pour les retours. Votre code est exactement ce que j'ai écrit. Il échoue dans "Shared_Ptr :: checked_delete" au chèque statique "Typedef Char Type_must_be_commlete [Tailleof (T)? 1: -1];"


@ToChight, si vous utilisez votre propre Delier qui le fait bien, cela ne devrait pas manquer comme ça. Assurez-vous de définir votre CustomDeleter de telle manière que son corps survient après la définition de lua_state .



1
votes

Il semblait étrange que boost :: Shared_ptr code> nécessiterait un type complet d'instanciation, alors j'ai écrit ce petit test qui démontre le contraire (code à la fin).

Je crois que Le problème n'est pas avec le type qui doit être complet, mais avec le deuxième argument que vous passez au constructeur partagée_ptr code>, qui ressemble à une fonction de membre. Le deuxième argument doit être appelé quelque chose d'appeler avec un seul argument de pointeur. Si vous souhaitez utiliser une fonction de membre de votre wrapper, vous pouvez utiliser boost :: lid code> pour adapter l'interface. P>

peut-être que vous vouliez dire ?: p>

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


0 commentaires

0
votes

étant donné qu'un lua_state * ne peut pas être cloné, copier un objet de luastation significatif? Quelles sont les sémantiques attendues de copier un objet aussi inconfortable?

Le comportement que vous semblez vouloir est Copie peu profonde - et la meilleure façon de le faire est que Luastate d'être inconfortable et de gérer la durée de vie du Lua_State, puis vous pouvez transmettre l'état comme un < Code> Shared_PTR .


0 commentaires