7
votes

Comment empêcher toute personne de voler mon partage_ptr?

Alors, j'utilise boost :: Shared_ptr pour tous les différents avantages de comptage de référence Il fournit - Comptage de référence pour commencer, mais également la possibilité de copier, d'affecter et donc de stocker dans des conteneurs STL.

Le problème est que si je le transmettez à une seule fonction ou à un objet "malveillant", l'objet peut sauvegarder le PTR, puis je ne pourrai jamais le désaffecter sans la fonction étranger ni le but gentiment renoncer à sa propriété. .

En fin de compte, j'essaie de garder la propriété de l'objet explicite. J'abandonne cela en demandant au propriétaire de conserver le seul partage_ptr à l'objet et que les objets "invité" ne stockent que des faibles_ptrs à l'objet.

Je ne veux vraiment pas la partie "partagée" de Shared_PTR, mais je dois utiliser Shared_PTR afin de faire des faibles_ptrs. Je veux utiliser Scoped_Ptr, mais il est extrêmement limité puisque vous ne pouvez pas le copier. Vous ne pouvez pas la stocker dans un conteneur, vous ne pouvez pas donner de faibles_ptrs à partir de celui-ci et vous ne pouvez pas transférer la propriété à un nouveau manager.

Quelle est la solution?


2 commentaires

C'est le problème avec le partage, n'est-ce pas :(


Notez que toute personne avec un faible_ptr peut verrouillage () it. Ils peuvent donc toujours essayer de le voler, même si vous ne leur donnez jamais de propriété.


6 Réponses :


10
votes

Faites-le privé et fournissez une façade pour faire les opérations nécessaires. Personne ne voit jamais le pointeur. Je suppose qu'à ce moment-là, vous n'auriez même pas besoin d'un Shared_Ptr.


1 commentaires

+1 Pour Privé, bien que l'avantage évident de partagé_ptr Voici la possibilité d'obtenir faibly_ptr , qui permettent à l'utilisateur de savoir si l'objet d'origine est toujours en vie.



1
votes

Il est assez bon d'utiliser faibles_ptr pour les objets invités, comme vous l'avez décrit en question. Sinon, vous aurez un problème avec des pointeurs morts.

Je envisagerais de faire de l'application Reatheritect pour supprimer les fonctions / objets malveillantes "ou au moins corriger leur comportement.


2 commentaires

Comme il s'avère, je contrôle tout le code pour que je puis j'ai chuté en supprimant le "malveillant" (ou dois-je dire "naïf") code moi-même. Je vais continuer à utiliser partagée_ptrs et juste être plus prudent en utilisant des faibles_ptr chaque fois que je peux éventuellement, parce que j'ai besoin du chèque expiré (). Je déteste vraiment le faire de cette façon, car assez souvent, je me sens comme si je suis mon pire ennemi parce que je continue à enregistrer accidentellement partagée_ptrs lorsque je voulais enregistrer une faiblesse_ptr. Il semble que c'était un gros problème avec Shared_Ptrs en général, car ils sont souvent collants que vous le souhaitez.


Accepter cette réponse parce que c'est ce que j'ai personnellement fini, mais cela n'aiderait à personne qui a un contrôle limité sur le code. Merci à tout le monde d'avoir posté leurs solutions, ils vont tous bien pour moi. Je souhaite que Boost sortirait avec "propriétaire_ptr" ou quelque chose de ...



0
votes

Vous pouvez étendre la classe Shared_Ptr Boost et remplacer la suppression de la suppression de la force Supprimer le pointeur.

Le problème est vraiment que, si la bibliothèque ne libère pas ou libérant le Shared_PTR, il est susceptible de se référer quelque temps. À ce stade, votre demande tombera avec un SIGSEGV.

Je pense qu'il invalide totalement le but des pointeurs partagés.

La meilleure solution est de corriger la bibliothèque.

Autre solution, utilisez AOP pour supprimer le pointeur à la sortie de la fonction de la bibliothèque que vous appelez. Cela reste susceptible de casser.


0 commentaires

3
votes

ne passe pas autour de la boost :: objet partagé_ptr ... Même si vous stockez l'objet, en interne, à l'aide d'un boost :: Shared_ptr, vous devez vous assurer que les fonctions prennent votre objet en référence constante plutôt qu'une copie de le pointeur partagé. Depuis que vous auriez besoin de déréférence, le pointeur partagé afin de transmettre l'objet à une fonction qui passe par Const Référence, vous saurez s'il suit ce protocole ou non.


1 commentaires

Quelques règles de pouce pour passer les objets par pointeur ou référence: a) Passer par un pointeur uni / auto uniquement Si vous souhaitez transférer la propriété (fondamentalement_ptr constructeur uniquement) B) B) Si la callee doit conserver l'accès, peu importe quoi, passez Par partage_ptr Constons Référence ou valeur (passant par Shared_Ptr Référence non-Const a une sémantique très obscure, si vous commencez à y penser - utilisez-le uniquement lorsque vous avez vraiment besoin). Vous pouvez assurer cela sur le côté de l'appelant en casnant votre Shared_Ptr vers Const. c) Dans tous les autres cas, passez par (const) référence à l'objet. Vous pouvez assurer cela lorsque vous appelez aussi.



0
votes

Il n'y a vraiment pas de bonne solution pour ce que vous décrivez.

Vous ne pouvez pas utiliser Auto_PTR car vous ne transférez pas la propriété.

Si vous pouvez garantir le propriétaire survivent aux références, je vous recommande d'utiliser une valeur SCOPED_PTR / Store par la valeur du propriétaire, puis en passant un pointeur brut ou une référence à ceux qui en ont besoin.

Si les références peuvent survivre au propriétaire (et les références doivent être notifiées gracieusement), vous devez utiliser Shared_PTR / FAID_PTR. Mais, comme vous l'avez dit, vous ne pouvez empêcher aucune classe / fonction de verrouiller la faiblesse_ptr et «empêcher» la répartition. Mais, dans l'interface, ne passez pas le Shared_PTR, passez la faiblesse_ptr. Ce n'est aussi fort qu'une convention, mais il est dit "Ne tiens pas cela, ça peut partir".


0 commentaires

0
votes

Si vous voulez gérer vos objets dans ce paradigme propriétaire / appartenant, je vous recommande de faire quelque chose comme QT.

  1. Créez un objet de classe de base, que toutes les classes de votre système hériteront de. Chaque objet tient une trace de son parent / propriétaire et ses enfants.
  2. Utilisez un Setowner (propriétaire d'objet *) Méthode pour définir le propriétaire et que cette méthode assurez-vous que l'objet propriétaire est notifié sur le nouvel enfant.
  3. Le destructeur de l'objet doit supprimer tous les objets enfants lorsqu'il est détruit.
  4. Définissez une classe de modèle qui définit un pointeur intelligent à une sous-classe d'objet. Faites-le de sorte que l'objet notifie aucun point-point connecté intelligent sur sa destruction, de sorte que les valeurs deviennent nulles lorsque l'objet est détruit.

    choses à surveiller pour:

    1. Tous les objets doivent être alloués via un nouveau destructeur d'objets pour les interditer correctement.
    2. Si vous oubliez de définir le parent d'un objet, il fuit
    3. Les objets de manutention qui n'héritent pas d'objet sont difficiles, bien que cela puisse être fait en définissant une classe de modèle qui hérite d'un objet à les maintenir.

0 commentaires