7
votes

Comment éviter de spécifier Delier pour STD :: Shared_PTR à chaque fois qu'il est construit ou réinitialisé?

std :: unique_ptr code> a 2 paramètres de modèle, dont le second est le deleter à utiliser. Merci à ce fait, on peut facilement alias un unique_ptr code> à un type, ce qui nécessite un destructeur personnalisé (par exemple SDL_Texture code>), de la manière suivante:

using SDL_TextureSharedPtr = MySharedPtr<SDL_Texture, SDL2PtrDeleter>;


7 commentaires

Pourquoi ne pas envelopper la classe elle-même pour la rendre Raii conforme et ajuster Shared_ptr Shard_ptr (s)?


Je ne vois pas encore pourquoi vous avez vraiment besoin d'un Delier personnalisé. Ne mettrait pas sdl_destroytexture (PTR); au travaux destructeurs ainsi que le Delier par défaut?


@lorro: cela ne fonctionne que pour les textures. L'objectif est de travailler pour n'importe quel type T.


Une meilleure question est la suivante: pourquoi avez-vous tant d'endroits dans votre code où vous construisez ou réinitialisez des textures SDL? Cela devrait vraiment être localisé à un peu d'emplacements.


@lorro: Vous supposez que sdl_texture est un type C ++ avec un destructeur. Le point d'avoir supprimé du tout est de gérer des types qui ont aucun destructeurs , tels que des types créés par des bibliothèques basées sur C.


La troisième option n'est pas option :: STD :: Default_Delete n'est pas appliquée sur STD :: Shared_PTR, sauf si elle est transmise explicitement comme Delier au constructeur.


@ Dieterlücking Oui, tu as raison, mon erreur. Je vais éditer la question.


4 Réponses :


2
votes

Vous n'avez pas inclus, en option, héritage privé avec des directives copieuses pour exposer les fonctionnalités inchangées.

Il est plus simple que la réécriture de PTR partagé tandis que Usong une copie privée, mais vous permet d'écrire une réinitialisation personnalisée sans danger d'exposition.

Notez également que le PTR partagé a une conversion de CTR de PTR unique. Si vos fonctions d'usine créent des PTR uniques, ils peuvent être affectés à des PTR partagés si nécessaire, la commande correcte du Delier est utilisée. Éliminer les pointeurs bruts de votre code et le problème de réinitialisation disparaît.


3 commentaires

@nicol il répond directement "Ai-je manqué un moyen plus simple d'éviter de devoir spécifier un Delier pour STD :: Shared_Ptr Chaque fois que son instance est construite ou réinitialisée ()?" Ceci est une option qu'il a manquée qui est plus simple qu'une option énumérée.


@Yakk merci, voici un uppote. Pour être honnête, je devais google ce que vous entendez par «Copieux en utilisant directives pour exposer les fonctionnalités non modifiées», car je n'ai jamais rencontré en utilisant utilisé pour exposer les méthodes de parents privés ( Je suppose que mes rencontres avec privées héritage sont arrivées assez rarement en général). Ce Cette réponse est-elle effacée pour moi. Puis-je vous demander d'inclure un exemple d'échantillon de code, illustrant votre idée avec en utilisant des membres parent ou un lien vers la réponse que j'ai mentionnée, au profit des autres, qui, comme moi, pourraient être dans le foncé.


@Terra Heh, j'ai dit que c'était une réponse non grande. ;) Week-end occupé, fête des pères.



4
votes
using SDL_TexturePtr = unique_ptr<SDL_Texture, SDL2PtrDeleter>;

2 commentaires

La troisième option n'est pas option :: STD :: Default_Delete n'est pas appliquée sur STD :: Shared_PTR, sauf si elle est transmise explicitement comme Delier au constructeur.


@ Dieterlücking: il suffit de la lire, et merci, vous avez malheureusement raison. Maintenant fixé.



1
votes

Vous êtes trop raccroché sur la mise en place du Delier dans le type lui-même. Concentrez-vous plutôt sur où partagé_ptr les instances viennent de.

La solution la plus efficace à ce problème consiste à centraliser correctement où partagé_ptr s pour ce système est introduit. Il devrait y avoir une seule fonction qui les génère; Il est responsable de la fixation du Delier approprié.

Évidemment, un tel système n'offre aucune garantie. Cependant, si vous n'utilisez tout simplement jamais partagé_ptr :: réinitialiser (et vraiment, il y a peu de raisons de le faire) et vous ne construisez jamais directement une (copier / déplacement va bien, mais les autres constructeurs ne sont pas), Ensuite, vous êtes en sécurité. Si vous devez réaffecter un partagé_ptr à une nouvelle instance, utilisez simplement opérateur = ; C'est ce que c'est pour.

En fin de compte, ce n'est pas différent d'une base de code qui fait une utilisation libérale de make_shared .


0 commentaires

2
votes

Vous devriez pouvoir utiliser un Veneer : Xxx

qui peut être généralisé avec: xxx

Vous devez être capable de hériter des constructeurs: xxx < BlockQuote>

Il ne semble pas avoir été conçu pour être sous-classé, puisqu'il a un destructeur non virtuel

le papier référencé implique qu'il est sûr pour ce cas d'utilisation. Il serait intéressant d'avoir des références appropriées de la norme, cependant.


1 commentaires

Merci pour le lien. C'est bien, mais si je n'ai rien oublié, cela ne semble pas aborder la pièce concernant réinitialiser () .