C++
Idioma Pimpl
Buscar..
Observaciones
El idioma pimpl (p ointer a impl ementation, a veces se hace referencia a la técnica puntero o gato de Cheshire como opaco), reduce los tiempos de compilación de una clase moviendo todos sus miembros de datos privados en una estructura definida en el archivo .cpp.
La clase posee un puntero a la implementación. De esta manera, se puede reenviar, para que el archivo de encabezado no necesite #include
clases que se usan en las variables de miembros privados.
Cuando se utiliza el lenguaje pimpl, cambiar un miembro de datos privados no requiere volver a compilar las clases que dependen de él.
Lenguaje básico de Pimpl
En el archivo de cabecera:
// widget.h
#include <memory> // std::unique_ptr
#include <experimental/propagate_const>
class Widget
{
public:
Widget();
~Widget();
void DoSomething();
private:
// the pImpl idiom is named after the typical variable name used
// ie, pImpl:
struct Impl; // forward declaration
std::experimental::propagate_const<std::unique_ptr< Impl >> pImpl; // ptr to actual implementation
};
En el archivo de implementación:
// widget.cpp
#include "widget.h"
#include "reallycomplextype.h" // no need to include this header inside widget.h
struct Widget::Impl
{
// the attributes needed from Widget go here
ReallyComplexType rct;
};
Widget::Widget() :
pImpl(std::make_unique<Impl>())
{}
Widget::~Widget() = default;
void Widget::DoSomething()
{
// do the stuff here with pImpl
}
La pImpl
contiene el estado del Widget
(o parte / la mayor parte de él). En lugar de que la descripción del estado del Widget
se exponga en el archivo de encabezado, solo se puede exponer dentro de la implementación.
pImpl
significa "puntero a la implementación". La implementación "real" de Widget
está en pImpl
.
Peligro: unique_ptr
cuenta que para que esto funcione con unique_ptr
, ~Widget()
debe implementarse en un punto en un archivo donde el Impl
sea completamente visible. Puede =default
allí, pero si =default
donde Impl
no está definido, el programa puede fácilmente tener un formato incorrecto, no se requiere diagnóstico.