2012-01-31 15 views
11

Supongamos que tengo clase como esta (simplificado):¿Qué es este patrón de diseño? ¿Cómo usarlo?

class Foo_p; 
class Foo 
{ 
private: 
    Foo_p *p; 
public: 
    Foo(); 
    /* methods, etc... */ 
}; 

Esta clase es una parte de una API. El Foo_p es todas las partes privadas de la clase, que no son declaradas en la clase Foo, como de costumbre, sino en una clase declarada a futuro separada que solo es utilizada por la implementación subyacente no visible en el exterior.

He visto este patrón usado en un par de proyectos, ¿hay un nombre para él?

Además, ¿cómo lo uso correctamente (por ejemplo, seguridad de excepción, etc.)? ¿A dónde debería ir la implementación real? En la clase Foo, como de costumbre, ¿solo usando Foo_p para el almacenamiento de datos, o en la clase Foo_p con Foo siendo solo un envoltorio?

Respuesta

8

Esto se conoce es PIMPL. implementación privada/puntero a privado. La clase, Foo_p, su clase sería se ha implementado de forma privada y se ha accedido a través de un puntero para que en lugar de mostrar la clase verdadera a los clientes, solo puedan ver la interfaz pública que eligió para exponer. Básicamente, abstrae del encabezado los vestigios de los detalles de implementación presentes en los miembros protected y private.

Lo encontré difícil de manejar en VC++ - rompe la finalización del código. Es útil si está muy seguro de su implementación y no desea que los miembros private y protected se muestren en el encabezado.

Puse la implementación real de la clase Foo_p en el archivo cpp para la clase Foo, aunque esto puede haber sido la causa de la terminación del código incompleto, al menos no tengo que correr el riesgo de que la clase se reutilice por inclusión de su encabezado.

+0

No tanto los encabezados y los niveles normales de protección (público/privado) "esencialmente ocultar la aplicación"? –

+0

@Matthew: Desafortunadamente, no. Debe incluir encabezados de implementación, que a menudo pueden ser incómodos cuando dependen, por ejemplo, de los encabezados de Windows, que son despreciablemente malos. – Puppy

+0

@MatthewFlaschen: Sí, pero solo en el sentido de que no puedes acceder a él, pero aún puedes * ver *, al mirar el código. – bitmask

8

Ese es el lenguaje pimpl

Ver

+0

¡Gracias por los enlaces! – kralyk

+0

Los enlaces están muertos :( – pmb

+1

@pmb Gracias por la sugerencia. Solucionado los tres enlaces. _o.O enlaces permanentes ... cuando funcionaban, eran muy agradables_ :( – sehe

2

Es un puntero d que es un tipo de puntero opaco. Similar al idioma PIMPL.

Un tipo de puntero opaco de uso común en las declaraciones de clase C++ es d-pointer. El d-puntero es el único miembro de datos privados de la clase y apunta a una instancia de una estructura. Nombrado por Arnt Gulbrandsen de Trolltech, este método permite a las declaraciones de clase omitir los miembros de datos privados , excepto el puntero d mismo.[6] El resultado es que más de la implementación de la clase está oculta, que agregar nuevos miembros de datos a la estructura privada no afecta la compatibilidad binaria con , y que el archivo de encabezado que contiene la declaración de clase solo tiene que # incluya esos otros archivos que se necesitan para la interfaz de clase , en lugar de su implementación. Como un beneficio lateral , las compilaciones son más rápidas porque el archivo de encabezado cambia menos a menudo. El d-puntero se usa mucho en las bibliotecas Qt y KDE.

https://en.wikipedia.org/wiki/Opaque_pointer#C.2B.2B

+0

Cita tus fuentes. –