Versteckt private Mitglieder der C ++ Bibliothek

7

Ich habe eine Bibliothek geschrieben (egal, was sie tut), die offensichtlich ihre Header-Datei hat. Jetzt möchte ich private Elemente dieser Header-Datei verbergen. Wenn ich meine Bibliothek jemandem anbiete, sollte er / sie nur öffentliche Mitglieder sehen (vorzugsweise keine Klassendefinition, nichts anderes als Funktionsdefinitionen). Ein Weg wäre die Erstellung eines C-style-Headers, der eine Art "init" -Methode enthält, die zum Erstellen einer Instanz der tatsächlichen Bibliotheksklasse verwendet wird, und der Benutzer muss einen Zeiger dieses Objekts an jede Funktion übergeben mach den Job.

Ist es eine gute Übung?

Gibt es andere öffentlich akzeptierte Möglichkeiten, so etwas zu tun?

Vielen Dank im Voraus.

    
khajvah 09.07.2013, 17:27
quelle

5 Antworten

11

Zusätzlich zu dem Factory-Muster (das meiner Meinung nach unhandlich werden kann), können Sie auch Ihre privaten Mitglieder hinter einem PIMPL verstecken (Pointer to IMPlementation):

%Vor%

Dies hat den Vorteil, dass die Implementation auf Kosten einer einzelnen Zeigerindirection nicht viel anders ist als das typische vererbungsbasierte Factory-Muster.

Dies kann auch ABI-stabil sein. Änderungen an Ihrer Implementierung wirken sich nicht auf die Verknüpfung aus, da für den Rest des Programms keine Änderungen sichtbar sind. Dies ist ein gutes Muster, das zum Beispiel bei der Implementierung von gemeinsam genutzten Objekten verwendet wird.

Es ist auch ein gängiges C ++ - Idiom, also werden andere C ++ - Programmierer es ohne Frage erkennen.

Im Fall einer Klasse, die dem Singleton-Muster folgt, können Sie das PIMPL überhaupt nicht aufdecken und einfach die gesamte Implementierung in ein anonymes namespace in Ihrer .cpp -Datei schreiben, wo Sie soviele setzen können Zustand und private Funktionen, wie Sie es wünschen, ohne es in Ihrer Schnittstelle zu erwähnen.

    
greyfade 09.07.2013, 17:52
quelle
6

Sie können eine öffentlich sichtbare Schnittstelle erstellen. Erstellen Sie eine abstrakte Klasse mit den Funktionen, die Sie bereitstellen möchten, und lassen Sie sie dann von Ihrer Implementierung erweitern.

Zum Beispiel eine Schnittstelle:

%Vor%

Und die Implementierung:

%Vor%

Dann exportieren Sie nur die Symbole für Interface. Damit der Benutzer der Bibliothek Instanzen von Interface erhält, die tatsächlich Implementierungen sind, müssen Sie eine Factory bereitstellen:

%Vor%     
Eric Finn 09.07.2013 17:34
quelle
2

Basierend auf Eric Finns Antwort können Sie einfach eine interface -Klasse deklarieren, um all Ihre öffentlichen Methoden zu berücksichtigen als Ihre API, und verstecken Sie alle Implementierungen und private Mitglieder / Methoden in der Implementierungsklasse, die interface -Klasse erbt, hier ist das Beispiel:

Ihre Header-Datei: my_api.h

%Vor%

Ihre Implementierung (shared library): my_api.cpp (Benutzer sehen dies nicht, wenn Sie eine shared library erstellen) Sie können also alle Ihre Implementierungs- und privaten Methoden / Mitglieder hier verbergen

%Vor%

Wie der Benutzer Ihre API verwendet:

%Vor%

Ausgabe:

%Vor%

In diesem Muster ist Ihre API nur eine abstrakte Klasse, die wie eine Factory funktioniert. Sie können die virtuelle Methode auch in verschiedenen Klassen implementieren und angeben, welche Instanz Sie aufrufen möchten.

    
Charles Chow 25.09.2014 01:25
quelle
1

Ich denke, Sie müssen Dynamic Link Library (dll) erstellen.

Bitte werfen Sie einen Blick auf diesen Link:

    
Rm ko 09.07.2013 17:31
quelle
0

Vielleicht möchten Sie sich die Umschlag- / Buchstabensprache, das Brückenentwurfsmuster oder das Proxy-Muster ansehen. Im Grunde würden Sie eine äußere (öffentliche) Klasse erstellen, die Ihre öffentlichen Methodenaufrufe nur an die innere (private) Klasse weiterleitet. Ihr InnerClass.h-Header muss nur in Ihren OuterClass.cpp- und InnerClass.cpp-Quelldateien sichtbar / bekannt sein.

Jedes dieser Muster bietet einen Mechanismus zum Trennen der Implementierung von der Schnittstelle, so dass der Aufrufer nicht mit der Implementierung verbunden ist. Manchmal ist es wünschenswert, Compiler-Abhängigkeiten von großen C ++ - Projekten zu reduzieren. Ein weiterer häufiger Grund dafür ist, wenn Sie die Implementierungsdetails ausblenden möchten, damit der Aufrufer nur einen einzelnen undurchsichtigen Zeiger sieht.

%Vor%     
Paul Dardeau 09.07.2013 17:37
quelle