Dans la plupart de mes programmations maintenant un jour, je mets tout dans un pointeur intelligent et oubliez-le em>. La ressource est correctement gérée 99,9% du temps. C'est vraiment grand et meilleur qu'un mécanisme de collecte des ordures. Cependant, une fois de temps en temps, la ressource détenue par un pointeur intelligent doit être explicitement libérée avant de pouvoir le réaffecter une nouvelle instance. Quelque chose comme ceci: p> si je manque l'appel existe un motif / algorithme / quelque chose qui gère un tel cas de manière plus propre? P> p> r.reset () code>, la ressource peut soit utiliser une grande monture de mémoire ou de disque L'espace et réaffectant sans la première réinitialisation est susceptible de causer des problèmes sur des ordinateurs plus petits. Soit cela, soit la ressource est verrouillée de sorte qu'elle ne peut donc pas être réaffectée avant de libérer explicitement. P>
3 Réponses :
Normalement, vous venez de mettre le Si cela ne convient pas à quelque raison que ce soit, lors de l'instanciation, vous pouvez mettre une fonction de destructeur personnalisée dans le Si le aussi, pourquoi utiliser réinitialiser () code> à l'intérieur du destructeur du
My_Resource Code> Classe. P>
std :: Shared_ptr code> qui appelle le
réinitialiser () code> puis Supprime la ressource. P>
partagé_ptr code> n'atteint pas le refcount 0 - Êtes-vous sûr de l'utiliser correctement? Il y a
std :: faible_ptr code> - une classe d'utilitaire pour
Shared_ptr code> - faite dans l'ensemble du but de la sécurité et de la répartition en temps utile. P>
make_shared code> et instatiez le nouveau
my_resource code> au lieu d'utiliser simplement une fonction init de
my_resource code> qui appellera automatiquement
() code> si nécessaire? p>
Le réinitialiser () code> fonctionne. Je n'ai pas de problème loop i>. Il s'agit davantage de type de ressource spécifique qui nécessite une instance de courant avant de pouvoir être réaffectée. (Par exemple, parce que l'instance actuelle a une serrure qui empêcherait une nouvelle allocation jusqu'à ce que le verrou soit libéré.)
@Alexiswilke J'ai mal compris votre question. Il semblait que vous devez appeler une fonction spécifique des ressources avant la destructeur de la ressource. Il serait plus clair si vous avez écrit r = {}; code> au lieu de
r.reset (); code> partiellement, car dans un autre endroit que vous avez écrit
r-> réinitialiser (); code>
Ouais, j'ai corrigé le deuxième cas dans la question (au moins). Malheureusement I>, vous ne pouvez pas modifier et corriger les commentaires ...
Bien que cela puisse sembler bizarre, je pense que cela peut être mieux exprimé comme une sémantique de déplacement. Voici pourquoi:
Le nouvel objet de ressource que vous créez est un remplacement de l'ancien. Supposons que le remplacement est transparent à vos utilisateurs (c'est-à-dire qu'ils perçoivent le nouvel objet de ressources et l'ancien comme identique). Par conséquent, c'est comme si vous avez effectué une copie imaginée de l'ancien objet pour en obtenir le nouveau, puis détruisez l'ancien. Cela correspond à l'intention de déplacer la sémantique. P>
donc my_resource code> doit avoir un constructeur de déplacement: p>
Je vois fondamentalement deux façons de s'approcher cela. Le premier consiste à envelopper la séquence de réinitialisation-Attribuer une seule fonction et ne jamais attribuer directement. Je ferais probablement cela comme tel c'est assez facile et rapide à faire, mais il ne vous évitera pas d'appeler accidentellement l'affectation directement et je ne vois pas un moyen de faire cela Si vous continuez à utiliser L'autre alternative écrit une enveloppe autour de Notez également que la bibliothèque standard réinitialise intentionnellement dans cet ordre de sorte que nous ne supprimons pas l'ancienne ressource si la nouvelle allocation jette. p> p> partagé_ptr code>. p>
partagée_ptr code> qui vient d'envoyer la plupart des appels de fonction et des modifications
réinitialiser code> et affectation de telle sorte qu'il fonctionnera d'abord puis crée la nouvelle ressource. C'est un peu de travail à faire et il est facile d'obtenir un bogue dans ceci (surtout si vous faites gâcher des références universelles si vous essayez de vous épargner des constructeurs). Il sera également gênant d'interagir avec un autre code qui utilise des pointeurs STD Smart et constituera un processus de refactorisation majeur. Mais vous ne pouvez pas le gâcher en appelant accidentellement une mission (au moins probablement pas). P>
Pour éviter les appels directs vers le constructeur, nous pouvons rendre cette fonction statique et cacher le constructeur ordinaire comme privé. Ce serait proche d'avoir un motif d'usine.
Cela ressemble plus à la typographie forte, comme lorsque vous créez des types d'emballage pour des mètres et des secondes, même s'ils ne sont que des chiffres de telle sorte que vous ne puissiez pas les ajouter par erreur.
Le problème avec une "quelle est la pratique de la manutention" x> en C ++ "de question est que, invariablement, lorsque vous posez cette question à trois développeurs C ++, vous obtiendrez quatre réponses différentes.
Je ne comprends pas ça.
r = std :: make_shared (avec_this_id); code> fait
r-> réinitialiser (); code>. Cela fait partie de ce qui le rend intelligent. Si vous appelez manuellement la libération, c'est la solution pour vous, alors il y a de gros problèmes quelque part.
@ Nathanoliver-Reinstatetemonica sur une réaffectation, le
R-> réinitialiser () code> L'appel se produit lorsque la variable est attribuée, ce qui signifie que l'instance actuelle de la ressource est conservée jusqu'à une fois la nouvelle instance allouée. Si la ressource détient une serrure contre la ressource, sans la réinitialisation explicite, elle échoue. Un autre problème potentiel est lorsque vous allouez un très grand tampon. Cela va être alloué deux fois jusqu'à ce que la mission se produise (bien que cela fonctionne à moins que vous ne manquiez pas de mémoire).
Voulez-vous vraiment appeler
r-> réinitialiser () code> (donc
my_resource :: réinitialiser code>) ou
r.reset () code> (donc
Shared_ptr :: réinitialiser code>)?
@ N314159 AH, désolé, oui
r.reset () code>, j'ai fait une mise à jour. Merci d'avoir fait remarquer cela.