J'utilise habituellement un boost :: scoped_ptr pour Pimpl's (pour une raison pour une raison parce que je ne reçois pas de surprises si j'oublie de traiter le constructeur de copie)
avec des modèles, mais je ne peux pas simplement mettre le destructeur dans Le fichier CPP où l'IPL est entièrement défini afin de répondre aux exigences du destructeur de Scoped_Ptr. Cela fonctionne de toute façon mais je ne suis pas sûr de bien vouloir travailler ou juste par hasard. Y a-t-il des «meilleures pratiques» ou de la norme? Scoped_ptr est-il le meilleur pointeur intelligent pour PIMPLS dans des classes non copieuses? p>
3 Réponses :
Il arrive que Sutter Herb a commencé à écrire ses gotws après une longue période. L'un des premiers nouveaux sont liés à "Pare-feu de compilation". P>
Vous voudrez peut-être jeter un oeil à: p>
gotw # 100: pare-feu de compilation (Difficulté: 6/10) 10) P>
et p>
gotw # 101: pare-feu de compilation, partie 2 (Difficulté: 8/10) 10) P >
Cool j'aime ses livres. Il semble avoir répondu à ma question sur le type de pointeur à utiliser en utilisant uniques_ptr.
On dirait que l'herbe est achetée dans la plus grande complexité est une meilleure philosophie. Toutes ses solutions à base standard introduisent une complexité supplémentaire pour aucun gain réel.
En ce qui concerne les modèles, cela n'a aucun sens d'utiliser l'idiome pimpl pour
les détails de la mise en œuvre de l'en-tête. Dans l'absence de boost :: partagé_ptr code> ne nécessite pas une définition complète autre que
le point d'instanciation - dans le constructeur, dans le cas d'un
pimpl.
boost :: partagé_ptr code> est pas fort> approprié pour l'idiome pimpl,
Cependant, puisqu'il donne une sémantique très inattendue (sémantique de référence
pour l'affectation ou la copie); Si vous voulez vraiment la complexité supplémentaire d'un
pointeur intelligent,
boost :: scoped_ptr code> serait plus approprié (mais il
nécessite une définition complète au point que son destructeur est
instancié). P>
exportation code>,
Tous les détails de la mise en œuvre d'un modèle de classe doivent être inclus
partout le modèle est utilisé, alors la motivation derrière le pimpl
idiome cesse d'exister. p>
Deux ans plus tard, je comprends bien la situation beaucoup mieux, dans l'intérêt de garder la pile Dépassement des réponses pertinentes et à jour ici est de savoir comment je répondrais aujourd'hui à la question. p>
Le principe de ma question initiale est quelque peu défectueux. La raison d'utiliser le pimpl-idiom consiste à masquer les détails de la mise en œuvre du compilateur. Cela se fait en stockant la mise en œuvre via un pointeur opaque (pointeur à un type de données déclaré mais non défini). Cela peut réduire considérablement la quantité d'en-têtes nécessaires par d'autres unités de compilation qui interagissent avec la classe et accélèrent ainsi l'heure de compilation. Dans le cas du modèle de ma question, il est nécessaire que le type t soit parfaitement connu au point d'instanciation qui, en pratique, nécessite que le type de l'implémentation soit complètement défini dans la mesure où Il existe d'autres raisons de contenir des données de classes via un pointeur privé, par exemple, il permet une mise en œuvre facile du déplacement et de l'échange sans jeton et est également bon si votre classe doit remplir une garantie d'exception forte (voir copie et échange idiom Quel est l'idiome de copie-and-swap? ). D'autre part, il ajoute une couche d'indirection (entraînant souvent une cache Mlle) sur tous les accès à l'IPL et à une allocation de tas / distribution de la transaction à la création et à la destruction de l'IPL. Celles-ci peuvent être des pénalités de performance substantielles, cette solution ne devrait donc pas être considérée comme une balle d'argent. p>
Si vous pouvez utiliser c ++ 11, STD :: unique_ptr doit être utilisé à la place de boost :: scoped_ptr. p> C
Ce type de mise en œuvre PIMPL n'a aucun sens car afin d'instantiier le modèle C, vous devez savoir que le type T. pimpl, d'autre part, cache entièrement un équivalent de T de l'utilisateur.
@Vladlazarenko hmm, j'ai pensé Boost boost :: Scoped_Ptr travaille aussi bien sur des classes prédéclarées. Dans ce cas, cela dépend si T est défini ou prédeclamé. L'instance de ce scoped_ptr serait cachée dans la mise en œuvre (pimpl_ (nouveau t ()).
@DAVIDFEURLE: Pas vraiment, pour que ce modèle fonctionne, la taille de
t code>, ainsi que son interface, doit être exposée, car des "clients" doivent instancier le modèle. Par exemple, où appelez-vous
nouveau t () code>? Vous ne pouvez pas masquer cela dans le fichier "CPP" car il doit être dans le modèle. Donc ce n'est pas pimpl.
@Vlad Lazarenko Bon point. Je vois où j'ai commis mon erreur et pourquoi ça marche
Donc, on dirait dans ce cas depuis que je dois définir de toute façon t de toute façon, je dois simplement en faire un membre privé pour économiser des coûts.
PIMPL est utilisé pour masquer les détails d'une classe donnée. Quels détails de classe voulez-vous cacher ici?