2012-04-26 8 views
15

Vengo de un fondo de C# y recientemente comencé a aprender C++. Una de las cosas que he encontrado es el idioma pimpl. Hice el desarrollo de C# para algunas grandes empresas, pero nunca lo encontré.¿El modismo de pimpl se usa en C#?

Quizás esto sea incorrecto, pero entiendo que es necesario en C++ debido al uso de archivos de encabezado y ninguna opción de clase parcial.

Pero en C# creamos aplicaciones usando librerías de clase todo el tiempo. Si algo cambiaba en el código de la biblioteca, lo recompilaríamos en un dll y haríamos referencia al nuevo archivo DLL en el proyecto de la aplicación.

Realmente no entiendo por qué no se puede hacer lo mismo con C++. Pimpl solo se ve como un feo truco para mí.

+4

No es "necesario" en C++, simplemente está ahí para ahorrar en tiempos de compilación (y en algunos casos para mantener la compatibilidad binaria). Si C++ compilado/vinculado tan rápido como C compila, dudo que alguien se moleste. – ildjarn

+1

Puede encontrar la publicación de Eric Lippert, [How Many Passes] (http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx), de interés. – Brian

Respuesta

26

¿Es el idioma pimpl utilizado en C#?

Eso depende de a qué te refieres con este modismo.

La expresión idiomática en cuestión consiste esencialmente en separar los detalles de implementación de un tipo en una clase y el área de superficie pública en una clase contenedora que simplemente se aferra a un puntero a la clase de implementación.

Esto tiene dos ventajas.

Primero, en C++ puede conducir a mejoras en el tiempo de compilación porque los consumidores de la superficie pública solo necesitan analizar el archivo de encabezado que contiene el área de superficie pública; no necesitan analizar el archivo de encabezado que contiene los detalles de implementación.

En segundo lugar, conduce a una separación muy clara de la interfaz de la implementación; la implementación puede cambiar completamente sin que haya ningún impacto sobre el consumidor, porque el consumidor nunca ve los detalles de la implementación.

El primer beneficio es sin importar en C#. El compilador de C# es rápido. (En gran parte, por supuesto, porque el lenguaje fue diseñado para ser rápido de compilar).

El segundo beneficio es de gran utilidad en C#. En C#, la forma idiomática de implementar este patrón sería hacer una clase privada anidada que haga el trabajo "real" y una clase pública que sea solo una fachada con el área de superficie pública.

Una técnica más me gusta en C# es hacer que la clase pública la clase base de de la clase anidada privada, ponga la clase base de un constructor privado para evitar la extensión de terceros, y utilizar el patrón de la fábrica para repartir casos de la clase anidada privada.

Realmente no entiendo por qué no se puede hacer lo mismo con C++.

Luego lo animo a intentar escribir un compilador de C++ que lo haga. O bien logrará crear un compilador de C++ mucho más rápido, o descubrirá por qué no se puede hacer lo mismo en C++. ¡Te beneficias de cualquier manera!

+2

¿Qué beneficio hay en crear una clase anidada privada, en lugar de omitir la clase anidada privada pero aún usar un constructor privado y un método de fábrica? ¿No podría ocultar los detalles de implementación haciendo que los miembros y campos relevantes sean privados? – Brian

+4

@Brian: Claro, si tienes una clase trivial que es completamente autónoma, hazlo todo en una sola clase. Pero, ¿qué sucede si tiene una cuenta bancaria de clase base y clases derivadas SavingsAccount y ChequingAccount, y luego más clases derivadas de ellas ... y desea que todas las clases, excepto la clase base, sean detalles privados de implementación de BankAccount? Podría convertirlos en internos de un ensamblado, o podría convertirlos en privados para un tipo. Este último enfatiza * a tus compañeros de trabajo * que estas clases son detalles de implementación privada, no un juego justo para su reutilización. –

+0

Bueno, hay algunos esfuerzos para volver a pensar en el modelo de compilación para ANSI C++ ver "Módulos C++". Sin embargo, el resultado es al menos incierto. Si eres un escritor de bibliotecas ANSI C++, o bien limpias C++ moderna (y publicas el código fuente), o haces C++ "práctico" (desplegable, reutilizable, protegible) que está en sus límites lleno de "hacks" y no ANSI más ... –

4

Sí, es (un "truco"). Es causado por un modelo de compilación basado en texto para ANSI C++: el compilador necesita ver la representación textual del código para generar algo útil. No es que tenga que ser así, pero así es como se hace hoy.

1

Como Eric señaló, la expresión de pimpl tiene dos propósitos. Solo agregaría que el segundo propósito (separar la interfaz y la implementación) es uno de los patrones de diseño de software conocidos: Bridge (también conocido como Handle/Body, creo). Puede leer más al respecto here

Cuestiones relacionadas