2012-04-26 5 views
15

Ich komme aus einem C# -Hintergrund und habe kürzlich angefangen, C++ zu lernen. Eines der Dinge, auf die ich gestoßen bin, ist das Pimpl-Idiom. Ich habe C# -Entwicklung für einige große Firmen gemacht, bin aber nie darauf gestoßen.Wird das Pimpl-Idiom in C# verwendet?

Vielleicht ist das falsch, aber mein Verständnis ist, dass es in C++ wegen der Verwendung von Header-Dateien und keine partielle Klassenoption notwendig ist.

Aber in C# würden wir ständig Anwendungen mit Klassenbibliotheken erstellen. Wenn sich etwas im Bibliothekscode geändert hat, würden wir es erneut zu einer DLL kompilieren und die neue DLL im Anwendungsprojekt referenzieren.

Ich verstehe nicht wirklich, warum das gleiche mit C++ nicht getan werden kann. Pimpl sieht für mich einfach wie ein hässlicher Hack aus.

+4

Es ist nicht "notwendig" in C++, es ist nur da, um Build-Zeiten zu sparen (und in einigen Fällen binäre Kompatibilität zu erhalten). Wenn C++ so schnell kompiliert/verlinkt wird, wie C# kompiliert wird, bezweifle ich, dass irgendjemand sich darum kümmern würde. – ildjarn

+1

Sie können Eric Lippert's Beitrag finden, [Wie viele Pässe] (http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx), von Interesse. – Brian

Antwort

26

Wird das Pimpl-Idiom in C# verwendet?

Das hängt davon ab, was Sie mit diesem Idiom meinen.

Das fragliche Idiom besteht im Wesentlichen darin, die Implementierungsdetails eines Typs in eine Klasse und die öffentliche Oberfläche in eine Wrapperklasse zu trennen, die einfach einen Zeiger auf die Implementierungsklasse festhält.

Dies hat zwei Vorteile.

Erstens kann es in C++ zu Verbesserungen in der Kompilierzeit führen, da die Benutzer der öffentlichen Oberfläche nur die Header-Datei mit der öffentlichen Oberfläche analysieren müssen; Sie müssen die Headerdatei mit den Implementierungsdetails nicht analysieren.

Zweitens führt es zu einer sehr sauberen Trennung der Schnittstelle von der Implementierung; Die Implementierung kann sich völlig ändern, ohne dass es jemals Auswirkungen auf den Verbraucher hat, da der Verbraucher die Implementierungsdetails nie sieht.

Der erste Vorteil ist in C# egal. Der C# -Compiler ist schnell. (Zu einem großen Teil natürlich, weil die Sprache entworfen wurde, um schnell kompiliert zu werden.)

Der zweite Vorteil ist von beträchtlichem Gebrauch in C#. In C# wäre die idiomatische Methode, dieses Muster zu implementieren, eine private verschachtelte Klasse zu machen, die die "echte" Arbeit und eine öffentliche Klasse ausführt, die nur eine Fassade mit der öffentlichen Oberfläche ist.

Eine Technik, die ich besonders gerne in C# ist die öffentliche Klasse der Basisklasse der privaten geschachtelten Klasse zu machen, der Basisklasse einen eigenen Fertigungsbetrieb an Dritte Erweiterung zu verhindern, und verwenden Sie die Factory-Pattern-Instanzen auszuzuteilen der privaten geschachtelten Klasse.

Ich verstehe nicht wirklich, warum die gleiche Sache nicht mit C++ getan werden kann.

Dann ermutige ich Sie zu versuchen, einen C++ - Compiler zu schreiben, der dies tut. Es wird Ihnen entweder gelingen, einen viel schnelleren C++ - Compiler zu erstellen, oder Sie werden herausfinden, warum dasselbe in C++ nicht möglich ist. Sie profitieren so oder so!

+2

Welchen Vorteil hat das Erstellen einer privaten geschachtelten Klasse, anstatt die private geschachtelte Klasse zu überspringen, aber trotzdem einen privaten Konstruktor und eine Factory-Methode zu verwenden? Konnten Sie die Implementierungsdetails nicht ausblenden, indem Sie nur die relevanten Mitglieder und Felder privat machen? – Brian

+4

@Brian: Sicher, wenn Sie eine triviale Klasse haben, die völlig in sich abgeschlossen ist, dann tun Sie alles in einer Klasse. Aber was ist, wenn Sie eine Basisklasse BankAccount und abgeleitete Klassen SavingsAccount und ChequingAccount haben und dann mehr abgeleitete Klassen von ihnen ... und Sie wollen, dass alle Klassen außer der Basisklasse private Implementierungsdetails von BankAccount sind? Sie könnten sie intern zu einer Assembly machen oder sie für einen Typ privat machen. Letzteres betont * Ihren Mitarbeitern * dass diese Klassen private Implementierungsdetails sind, nicht faires Spiel zur Wiederverwendung. –

+0

Nun, es gibt einige Anstrengungen, das Kompilierungsmodell für ANSI C++ zu überdenken, siehe "C++ Module". Das Ergebnis ist jedoch zumindest unsicher. Wenn Sie ein ANSI C++ - Bibliotheksschreiber sind, reinigen Sie entweder modernes C++ (und veröffentlichen Quellcode), oder Sie tun "praktisches" (einsetzbares, wiederverwendbares, schützbares) C++, das an seinen Grenzen voller "Hacks" und nicht ANSI ist mehr ... –

4

Ja ist es (ein "Hack"). Es wird durch ein textbasiertes Kompilierungsmodell für ANSI C++ verursacht: Der Compiler muss die textuelle Darstellung des Codes sehen, um etwas Nützliches zu erzeugen. Nicht, dass es so sein muss, aber so wird es heute gemacht.

1

Wie Eric darauf hingewiesen hat, hat das Pimpl-Idiom zwei Zwecke. Ich würde nur hinzufügen, dass der zweite Zweck (Trennung von Schnittstelle und Implementierung) eines der bekannten Software-Design-Muster ist: Bridge (auch bekannt als der Griff/Körper, denke ich). Sie können mehr darüber lesen here