141 votes

Pourquoi devrait-on utiliser le langage « PIMPL » ?

Document d'information:

Le PIMPL Idiome est une technique de mise en œuvre de la clandestinité dans laquelle un public de classe encapsule une structure ou d'une classe qui ne peut pas être vu à l'extérieur de la bibliothèque de la classe publique est partie.

Ce cache interne détails de mise en œuvre et les données de l'utilisateur de la bibliothèque.

Lors de la mise en œuvre de la cet idiome pourquoi vous placez les méthodes publiques sur la pimpl classe, et non pas la classe publique depuis le public des classes de méthode implementaions seraient rassemblés dans la bibliothèque et l'utilisateur n'a plus le fichier d'en-tête?

Pour illustrer, ce code met l'Purr() de la mise en œuvre sur l'impl classe et l'enveloppe.

Pourquoi ne pas mettre en œuvre Ronronner directement sur la classe publique?

//header file:
class Cat {
    private:
        class CatImpl;  // Not defined here
        CatImpl *cat_;  // Handle

    public:
        Cat();            // Constructor
        ~Cat();           // Destructor
        // Other operations...
        Purr();
};


//CPP file:
#include "cat.h"

class Cat::CatImpl {
    Purr();
...     // The actual implementation can be anything
};

Cat::Cat() {
    cat_ = new CatImpl;
}

Cat::~Cat() {
    delete cat_;
}

Cat::Purr(){ cat_->Purr(); }
CatImpl::Purr(){
   printf("purrrrrr");
}

72voto

Rob Wells Points 21714

Je pense que la plupart des gens se réfèrent à ce que la Poignée du Corps de l'idiome. Voir James Coplien du livre Avancée de la Programmation en C++ de Styles et d'expressions idiomatiques (lien Amazon). Il est également connu comme le Chat de Cheshire en raison de Lewis Caroll personnage qui s'estompe, jusqu'à ce qu'un sourire reste.

L'exemple de code devrait être réparti entre deux ensembles de fichiers source. Alors que Chat.h est le fichier qui est livré avec le produit.

CatImpl.h est inclus par Cat.cpp et CatImpl.cpp contient la mise en œuvre de CatImpl::Purr(). Ce ne sera pas visible pour le public à l'aide de votre produit.

Fondamentalement, l'idée est de cacher autant que possible de la mise en œuvre de la fom regards indiscrets. Ceci est particulièrement utile lorsque vous avez un produit commercial qui est envoyé comme une série de bibliothèques qui sont accessibles via une API du client code est compilé contre et liés à.

Nous l'avons fait avec la réécriture de le ionas Orbix 3.3 produit en 2000.

Comme mentionné par d'autres, à l'aide de sa technique complètement découple la mise en œuvre à partir de l'interface de l'objet. Ensuite, vous n'aurez pas à recompiler tout ce qui utilise le Chat si vous voulez juste changer la mise en œuvre de Purr().

Cette technique est utilisée dans une méthode appelée la conception par contrat.

42voto

Xavier Nodet Points 2498
<ul> <li>Parce que vous voulez <code></code> pour pouvoir utiliser les membres privés de <code></code> . <code></code>ne serait pas autorisé un tel accès sans un <code></code> déclaration.</li> <li>Parce qu’alors vous ne mélangez pas les responsabilités : implémente une classe, une classe vers l’avant.</li> </ul>

15voto

Nick Points 4572

Si votre classe utilise l’idiome pimpl, vous pouvez éviter de changer le fichier d’en-tête sur la classe publique.

Cela vous permet d’ajouter/supprimer des méthodes à la classe pimpl, sans modifier le fichier d’en-tête de la classe externe. Vous pouvez également ajouter/supprimer des #includes à la pimpl trop.

Lorsque vous modifiez le fichier d’en-tête de la classe externe, vous devez recompiler tout ce #includes il (et si aucun de ceux qui sont des fichiers d’en-tête, vous devrez recompiler tout ce #includes eux et ainsi de suite)

14voto

ChrisN Points 10734

Vous pouvez trouver l’article de Herb Sutter GotW 24 : Compilation pare-feu utile.

7voto

Wilka Points 13239

Généralement, la seule référence à la Pimpl classe dans l'en-tête pour le Propriétaire de la classe (Cat dans ce cas) serait une déclaration anticipée, comme vous l'avez fait ici, parce que cela peut grandement réduire les dépendances.

Par exemple, si votre Pimpl classe a ComplicatedClass en tant que membre (et pas seulement un pointeur ou une référence à cela), alors vous auriez besoin d'avoir ComplicatedClass entièrement définie avant son utilisation. Dans la pratique, cela signifie notamment "ComplicatedClass.h" (qui sera aussi indirectement comprennent rien ComplicatedClass dépend). Cela peut conduire à une seule tête de remplissage en tirant dans le tas et des tas de trucs, ce qui est mauvais pour la gestion de vos dépendances (et votre temps de compilation).

Lorsque vous utilisez le pimpl idion, vous avez seulement besoin de #inclure la substance utilisée dans l'interface publique de votre type de Propriétaire (ce qui serait de Chat ici). Ce qui rend les choses meilleures pour les personnes à l'aide de votre bibliothèque, et signifie que vous n'avez pas besoin de vous soucier de personnes, selon certains, de la partie interne de votre bibliothèque, soit par erreur, soit parce qu'ils veulent faire quelque chose que vous ne laissez pas de sorte qu'ils #define privé public avant y compris vos fichiers.

Si c'est une simple classe, il n'y a généralement pas de raison d'utiliser un Pimpl, mais pour les moments où les types sont assez grand, il peut être d'une grande aide (surtout en évitant de longs temps de construire)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X