2008-11-12 11 views
0

J'écris un projet de lib et de démo. Le projet ne se soucie pas de la version de la lib que j'utilise (je peux utiliser sdl, directx ou tout ce que j'aime comme backend gfx). Pour obtenir l'objet que je faisSupprimer ou supprimer virtuellement?

Obj *obj = libname_newDevice(); 

Maintenant, dois-je utiliser supprimer ou dois-je faire obj->deleteMe();? Je demande parce que je ne fais pas exactement nouveau alors je ne devrais pas faire la suppression? J'ai un obj->create(theType); qui renvoie une classe avec l'interface Obj. Ma vraie question est-ce que j'ai besoin d'un libname_deleteDevice(); ou est obj->deleteMe() bien puisque j'ai un deleteMe dans l'interface?

Répondre

2

Je voudrais aller un peu plus loin.
Si vous utilisez une fonction usine à créer, il peut être logique d'utiliser une fonction usine pour la détruire. En plus de cela pour rendre le tout agréable et exquis envelopper en toute sécurité dans un objet.

class ObjWrap 
{ 
    public: 
     ObjWrap() 
      :obj(libname_newDevice()) 
     {} 
     ~ObjWrap() 
     { libname_deleteDevice(obj);} 
    private: 
     ObjWrap(ObjWrap const&);  // Dont copy 
     void operator=(ObjWrap const&); // Dont copy 
     Obj* obj; 
}; // If you want to copy then you need to extra work on ref counting 
    // This may need some form of smart pointer. 
11

Puisque vous absentez la création à l'intérieur de libname_newDevice(), ce qui, je crois, n'est pas non plus un bon moyen, vous devriez détruire en utilisant quelque chose comme libname_destroyDevice (obj).

+0

Oui, la symétrie est agréable. Ensuite, vous devriez envelopper le tout dans un objet où ces deux fonctions sont appelées par le constructeur/destructeur. –

4

Veuillez essayer de clarifier votre question. Ce n'est pas clair pour moi. Pourquoi est-ce que vous parlez d'un arrière-plan graphique?

  • Est-ce pertinent à la question?
  • Demandez-vous comment vous devriez concevoir votre bibliothèque ou comment l'utiliser?

Il est recommandé d'avoir une fabrique d'objets pour créer l'objet. Je suppose que c'est le rôle de libname_newDevice().

La bibliothèque doit également fournir un moyen de supprimer l'objet (tel que obj->DeleteMe() ou libname_Delete(obj)). Ne comptez pas sur les delete de C++: l'appelant et la bibliothèque ont pu être compilés avec une version différente du compilateur, ce qui aurait des effets différents en ce qui concerne l'allocation de mémoire et de ressources. Il est donc plus sûr si votre lib supprime l'objet qu'il a créé.

+0

I gues graphiques ne sont pas pertinents. Spécifiquement je veux savoir si je devrais faire libname_Delete() ou si je devrais faire obj-> DeleteMe(); J'ai aussi un obj-> create (theType); –

+0

Il est plus sûr (sous Windows) si la lib supprime les objets qu'elle crée. Mais votre raisonnement pour pourquoi est faussé. –

0

Vous ne voulez certainement pas implémenter Obj :: deleteMe(). Il devrait faire quelque chose comme:

delete this; 

alors que vous étiez encore dans this-> deleteMe(). Suivez la suggestion de Jaywalker et faites en sorte que la fonction destroy prenne un Obj * comme paramètre.

+0

"supprimer ceci;" peut faire crawl la peau, mais ce n'est pas nécessairement mauvais. Les objets qui implémentent leur propre comptage de références doivent toujours le faire.Pour des exemples, voir Release() dans chaque "ma première implémentation COM". – RobH

1

Je pense que le meilleur moyen serait d'honorer RAII et d'avoir un objet encapsuleur de comptage de référence (vous pouvez même utiliser shared_ptr avec un deallocator personnalisé).