Ich frage mich also, ob diese Technik in der Praxis wirklich angewendet wird. Sollte ich es überall oder mit Vorsicht verwenden?
Natürlich wird es verwendet. Ich benutze es in meinem Projekt, in fast jeder Klasse.
Gründe für die Verwendung der PIMPL-Sprache:
Binäre Kompatibilität
Wenn Sie eine Bibliothek entwickeln, können Sie Felder hinzufügen / ändern, XImplohne die Binärkompatibilität mit Ihrem Client zu beeinträchtigen (was Abstürze bedeuten würde!). Da sich das binäre Layout der XKlasse nicht ändert, wenn Sie der Klasse neue Felder hinzufügen Ximpl, können Sie der Bibliothek in kleineren Versionsaktualisierungen sicher neue Funktionen hinzufügen.
Natürlich können Sie auch neue öffentliche / private nicht-virtuelle Methoden hinzufügen X/ XImplohne die binäre Kompatibilität zu brechen, aber das ist auf einer Stufe mit der Standard - Header / Implementierungstechnik.
Daten verstecken
Wenn Sie eine Bibliothek entwickeln, insbesondere eine proprietäre, ist es möglicherweise wünschenswert, nicht anzugeben, welche anderen Bibliotheken / Implementierungstechniken zur Implementierung der öffentlichen Schnittstelle Ihrer Bibliothek verwendet wurden. Entweder aufgrund von Problemen mit geistigem Eigentum oder weil Sie glauben, dass Benutzer versucht sein könnten, gefährliche Annahmen über die Implementierung zu treffen, oder einfach die Kapselung durch schreckliche Casting-Tricks zu brechen. PIMPL löst / mildert das.
Kompilierungszeit
Die Kompilierungszeit wird verkürzt, da nur die Quelldatei (Implementierungsdatei) von neu erstellt werden Xmuss, wenn Sie der XImplKlasse Felder und / oder Methoden hinzufügen / entfernen (was dem Hinzufügen privater Felder / Methoden in der Standardtechnik entspricht). In der Praxis ist dies eine übliche Operation.
Bei der Standard-Header- / Implementierungstechnik (ohne PIMPL) muss beim Hinzufügen eines neuen Felds Xjeder Client, der jemals zugewiesen wird X(entweder auf einem Stapel oder auf einem Heap), neu kompiliert werden, da die Größe der Zuordnung angepasst werden muss. Nun, jeder Client, der niemals X zuweist, muss ebenfalls neu kompiliert werden, aber es ist nur Overhead (der resultierende Code auf der Clientseite ist der gleiche).
Darüber hinaus muss die Standardtrennung von Header und Implementierung XClient1.cppneu kompiliert werden, auch wenn eine private Methode X::foo()hinzugefügt Xund X.hgeändert wurde, obwohl XClient1.cppdiese Methode aus Kapselungsgründen möglicherweise nicht aufgerufen werden kann! Wie oben ist es reiner Overhead und hängt damit zusammen, wie echte C ++ - Build-Systeme funktionieren.
Natürlich ist keine Neukompilierung erforderlich, wenn Sie nur die Implementierung der Methoden ändern (weil Sie den Header nicht berühren), aber dies entspricht der Standard-Header- / Implementierungstechnik.
Wird diese Technik für eingebettete Systeme empfohlen (bei denen die Leistung sehr wichtig ist)?
Das hängt davon ab, wie mächtig Ihr Ziel ist. Die einzige Antwort auf diese Frage lautet jedoch: Messen und bewerten Sie, was Sie gewinnen und verlieren. Beachten Sie außerdem, dass nur der Vorteil der Kompilierungszeit gilt, wenn Sie keine Bibliothek veröffentlichen, die von Ihren Clients in eingebetteten Systemen verwendet werden soll!
struct XImpl : public X. Das fühlt sich für mich natürlicher an. Gibt es ein anderes Problem, das ich verpasst habe?