2012-04-26 14 views
15

Provengo da uno sfondo C# e recentemente ho iniziato ad imparare il C++. Una delle cose che ho incontrato è l'idioma pimpl. Ho sviluppato C# per alcune grandi aziende, ma non l'ho mai incontrato.L'idioma di Pimpl è utilizzato in C#?

Forse questo è sbagliato, ma la mia comprensione è che è necessario in C++ a causa dell'uso di file di intestazione e nessuna opzione di classe parziale.

Ma in C# avremmo creato applicazioni utilizzando le librerie di classi tutto il tempo. Se qualcosa è cambiato nel codice della libreria, lo ricompiliamo in una DLL e facciamo riferimento alla nuova DLL nel progetto dell'applicazione.

Non capisco davvero perché la stessa cosa non può essere fatta con C++. Pimpl mi sembra un brutto scherzo.

+4

Non è "necessario" in C++, è semplicemente lì per risparmiare sui tempi di costruzione (e in alcuni casi per mantenere la compatibilità binaria). Se C++ compilato/collegato alla velocità di compilazione di C#, dubito che qualcuno si preoccupi di farlo. – ildjarn

+1

Potresti trovare il post di Eric Lippert, [How Many Passes] (http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx), di interesse. – Brian

risposta

26

L'idioma di pimpl utilizzato in C#?

Dipende da cosa intendi con questo idioma.

L'idioma in questione è essenzialmente quello di separare i dettagli di implementazione di un tipo in una classe, e l'area della superficie pubblica in una classe wrapper che si limita a tenere un puntatore alla classe di implementazione.

Questo ha due vantaggi.

Innanzitutto, in C++ può portare a miglioramenti nel tempo di compilazione perché i consumatori dell'area pubblica devono solo analizzare il file di intestazione contenente l'area della superficie pubblica; non hanno bisogno di analizzare il file di intestazione contenente i dettagli di implementazione.

In secondo luogo, porta ad una separazione molto netta dell'interfaccia dall'implementazione; l'implementazione può cambiare completamente senza che ci sia alcun impatto sul consumatore, perché il consumatore non vede mai i dettagli dell'implementazione.

Il primo vantaggio non ha importanza in C#. Il compilatore C# è veloce. (In gran parte ovviamente perché il linguaggio è stato progettato per essere veloce da compilare.)

Il secondo vantaggio è di notevole utilizzo in C#. In C# il modo idiomatico di implementare questo modello sarebbe quello di creare una classe nidificata privata che fa il lavoro "reale" e una classe pubblica che è solo una facciata con l'area della superficie pubblica.

Una tecnica mi piace particolarmente in C# è quello di rendere la classe pubblica della classe di base della classe privata nidificato, dare la classe base di un costruttore privato per evitare l'estensione di terze parti, e utilizzare il modello di fabbrica per distribuire le istanze della classe nidificata privata.

Non capisco davvero perché la stessa cosa non può essere fatta con C++.

Quindi vi incoraggio a tentare di scrivere un compilatore C++ che lo faccia. Riuscirai a creare un compilatore C++ molto più veloce, o scoprirai perché la stessa cosa non può essere fatta in C++. Beneficio in entrambi i modi!

+2

Che vantaggio c'è nella creazione di una classe nidificata privata, anziché saltare la classe nidificata privata, ma utilizzare comunque un metodo di costruzione e costruttore privato? Non potresti nascondere i dettagli di implementazione semplicemente rendendo privati ​​i membri e i campi rilevanti? – Brian

+4

@Brian: Certo, se hai una classe banale che è completamente autonoma, allora fai tutto in un'unica classe. Ma cosa succede se si dispone di una classe base BankAccount e classi derivate SavingsAccount e ChequingAccount e quindi più classi derivate da esse ... e si desidera che tutte le classi, ad eccezione della classe base, siano dettagli di implementazione privata di BankAccount? Potresti renderli interni a un assembly o renderli privati ​​di un tipo. Quest'ultima sottolinea * ai tuoi colleghi * che queste classi sono dettagli di implementazione privati, non un gioco leale per il riutilizzo. –

+0

Bene, ci sono alcuni sforzi per ripensare il modello di compilazione per ANSI C++ vedi "moduli C++". Tuttavia, il risultato è almeno incerto. Se sei uno scrittore di librerie ANSI C++, fai un C++ pulito e moderno (e pubblichi il codice sorgente), o fai un C++ "pratico" (distribuibile, riutilizzabile, proteggiabile) che è ai suoi confini pieno di "hack" e non ANSI altro ancora ... –

4

Sì, è (un "trucco"). È causato da un modello di compilazione testuale per ANSI C++: il compilatore deve vedere la rappresentazione testuale del codice per generare qualcosa di utile. Non che debba essere così, ma è così che è fatto oggi.

1

Come ha sottolineato Eric, l'idioma di Pimpl ha due scopi. Vorrei solo aggiungere che il secondo scopo (separare l'interfaccia e l'implementazione) è uno dei ben noti modelli di progettazione del software: Bridge (noto anche come Handle/Body credo). Potete leggere di più su di esso here

Problemi correlati