¿Por qué debería usarse el modismo "PIMPL"? [duplicar]

Resuelto JeffV asked hace 16 años • 11 respuestas

Antecedentes:

El modismo PIMPL (puntero a IMPLementation) es una técnica para ocultar implementaciones en la que una clase pública envuelve una estructura o clase que no se puede ver fuera de la biblioteca de la que forma parte la clase pública.

Esto oculta detalles y datos de implementación interna al usuario de la biblioteca.

Al implementar este modismo, ¿por qué colocaría los métodos públicos en la clase pimpl y no en la clase pública, ya que las implementaciones de los métodos de las clases públicas se compilarían en la biblioteca y el usuario solo tendría el archivo de encabezado?

Para ilustrar, este código coloca la Purr()implementación en la clase impl y también la envuelve.

¿Por qué no implementar Purr directamente en la clase pública?

// 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");
}
JeffV avatar Sep 13 '08 21:09 JeffV
Aceptado

Creo que la mayoría de la gente se refiere a esto como el modismo Handle Body . Consulte el libro de James Coplien Estilos y modismos de programación avanzados en C++ . También se le conoce como el Gato de Cheshire por el carácter de Lewis Carroll que se desvanece hasta que sólo queda la sonrisa.

El código de ejemplo debe distribuirse en dos conjuntos de archivos fuente. Entonces sólo Cat.h es el archivo que se envía con el producto.

CatImpl.h está incluido en Cat.cpp y CatImpl.cpp contiene la implementación de CatImpl::Purr() . Esto no será visible para el público que utilice su producto.

Básicamente, la idea es ocultar la mayor parte posible de la implementación a miradas indiscretas.

Esto es más útil cuando tiene un producto comercial que se envía como una serie de bibliotecas a las que se accede a través de una API con la que se compila y vincula el código del cliente.

Hicimos esto con la reescritura del producto Orbix 3.3 de IONA en 2000.

Como mencionaron otros, el uso de su técnica desacopla completamente la implementación de la interfaz del objeto. Entonces no tendrás que volver a compilar todo lo que usa Cat si solo quieres cambiar la implementación de Purr() .

Esta técnica se utiliza en una metodología llamada diseño por contrato .

Rob Wells avatar Sep 13 '2008 14:09 Rob Wells
  • Porque desea Purr()poder utilizar miembros privados de CatImpl. Cat::Purr()no se le permitiría dicho acceso sin una frienddeclaración.
  • Porque entonces no se mezclan responsabilidades: una clase implementa, una clase avanza.
Xavier Nodet avatar Sep 13 '2008 15:09 Xavier Nodet