Bei der Computerprogrammierung ist ein undurchsichtiger Zeiger ein Spezialfall eines undurchsichtigen Datentyps, eines als Zeiger auf einen Datensatz oder eine Datenstruktur eines nicht spezifizierten Typs deklarierten Datentyps.
Undurchsichtige Zeiger sind in mehreren Programmiersprachen vorhanden, darunter Ada, C, C ++, D und Modula-2.
Wenn die Sprache stark typisiert ist, können Programme und Prozeduren, die keine anderen Informationen über einen undurchsichtigen Zeigertyp haben T noch Variablen, Arrays und Datensatzfelder des Typs deklarieren. T Weisen Sie diesem Typ Werte zu und vergleichen Sie diese Werte auf Gleichheit. Sie sind jedoch nicht in der Lage, einen solchen Zeiger zu deaktivieren, und können den Inhalt des Objekts nur ändern, indem Sie eine Prozedur aufrufen, die die fehlenden Informationen enthält.
Undurchsichtige Zeiger sind eine Möglichkeit, die Implementierungsdetails einer Schnittstelle vor gewöhnlichen Clients auszublenden, sodass die Implementierung geändert werden kann, ohne dass die Module unter Verwendung davon neu kompiliert werden müssen. Dies ist auch für den Programmierer von Vorteil, da eine einfache Schnittstelle erstellt werden kann und die meisten Details in einer anderen Datei versteckt werden können. [1] Dies ist wichtig, um beispielsweise Binärcode-Kompatibilität durch verschiedene Versionen einer gemeinsam genutzten Bibliothek zu gewährleisten.
Diese Technik wird in Design Patterns als Brückenmuster beschrieben. Es wird manchmal als " Klassen behandeln " bezeichnet, [2] das " Pimpl Idiom " (für "Zeiger auf Implementierungs-Idiom"), [3] Compiler-Firewall idiom ", [4] " D-Pointer " oder" Cheshire Cat ", insbesondere bei der C ++ - Gemeinschaft. [2]
Beispiele [ edit ]
Ada [ edit ]
Paket Library_Interface ist vom Typ ] private ; - Operations ... private Typ Hidden_Implementation ; - Definiert im Gehäusekörper Griff . 19659016] ist Zugriff Hidden_Implementation ; Ende Library_Interface ; Der Typ Handle ist ein undurchsichtiger Zeiger für die Realimplementierung nicht in der Spezifikation definiert. Beachten Sie, dass der Typ nicht nur privat ist (um den Clients den direkten Zugriff auf den Typ und nur über die Vorgänge zu verbieten), sondern auch eingeschränkt (um die Kopie der Datenstruktur zu vermeiden und somit unzulängliche Verweise zu vermeiden).
Paket body Library_Interface ist Typ Hidden_Implementation ist . Datensatz ... - Die tatsächliche Implementierung kann beliebig sein. 19659049] end record ; - Definition der Operationen ... end Library_Interface ; Diese Typen werden manchmal als " Taft-Typen " bezeichnet. - benannt nach Tucker Taft, dem Hauptdesigner von Ada 95 - weil sie in der sogenannten Taft Amendment von Ada 83 eingeführt wurden. [5]
C [ edit ]
/ * obj .h * / struct obj ; / * * Der Compiler betrachtet struct obj als unvollständigen Typ. Unvollständige Typen * können in Deklarationen verwendet werden. * / size_t obj_size ( void ; void obo_setid struct obj * int ]; int obj_getid struct obj * 19659022]); / * obj.c * / #include "obj.h" struct obj { id id id }; / * * Der Anrufer wird die Zuweisung übernehmen. * Nur die erforderlichen Informationen bereitstellen * / size_t obj_size void ) { return sizeof ( struct obj ); } obj_setid struct obj * o int i ) { o id 19659076] = [19659033] ; } int obj_getid ( struct obj * o ] [19659907] (19659907]) o -> id ; } Dieses Beispiel zeigt einen Weg, um den Informationsverdeckungsaspekt (Einkapselung) der objektorientierten Programmierung unter Verwendung der C-Sprache zu erreichen. Wenn jemand die Deklaration von struct obj ändern wollte, ist es nicht erforderlich, alle anderen Module im Programm, die die Header-Datei obj.h verwenden, erneut zu kompilieren, es sei denn, die API wurde ebenfalls geändert. Es ist zu beachten, dass es wünschenswert sein kann, dass die Funktionen prüfen, ob der übergebene Zeiger nicht NULL ist, aber solche Überprüfungen wurden der Übersicht halber oben weggelassen.
C ++ [ edit ]
/ * PublicClass.h * / class publicClass [19659925] public publicac (); // Konstruktor PublicClass ( const PublicClass & ] // Copy constructor PublicClass ] ( PublicClass && ); // Move-Konstruktor PublicClass & operator const & ); // Kopierzuweisungsoperator ~ PublicClass (); // Destructor // Andere Operationen ... private : struct CheshireCat ; // nicht definiert unique_ptr CheshireCat d [pp] 19659200] // undurchsichtiger Zeiger };
/ * PublicClass.cpp * / #include "Pub licClass.h " struct PublicClass :: CheshireCat { int a int b b b ; 19659096]}; PublicClass :: PublicClass () : d_ptr ( neu (19659033] ())] ] { // nichts tun } PublicClass :: PublicClass ( const PublicClass & andere ] : d_ptr (19659074) neu CheshireCat ( * andere . d_ptr )) ) ) 19659228] // Nichts tun } PublicClass :: PublicClass ( PublicClass && ] ] ] ] ] default ; PublicClass & PublicClass :: operator = const const const const ss & other ) { * d_ptr = 19659076] other . d ; 19659107] return * Dies ; PublicClass :: ~ PublicClass (19659076] = 196590108]; Das D-Zeiger-Muster ist eine der Implementierungen des undurchsichtigen Zeigers . Es wird aufgrund seiner Vorteile häufig in C ++ - Klassen verwendet (siehe unten). Ein D-Pointer ist ein privates Datenmitglied der Klasse, das auf eine Instanz einer Struktur zeigt. Diese Methode erlaubt Klassendeklarationen, private Datenelemente außer dem D-Pointer selbst auszulassen. [6] Als Ergebnis
- Ein Großteil der Klassenimplementierung ist ausgeblendet.
- Das Hinzufügen neuer Datenelemente zur privaten Struktur wirkt sich nicht auf die binäre Kompatibilität aus.
- Die Header-Datei, die die Klassendeklaration enthält, muss nur die Dateien enthalten, die für die Klassenschnittstelle benötigt werden für seine Implementierung.
Ein weiterer Vorteil ist, dass Kompilierungen schneller sind, da sich die Header-Datei seltener ändert. Ein möglicher Nachteil des D-Pointer-Musters ist der indirekte Member-Zugriff über einen Pointer (z. B. Pointer auf Objekt im dynamischen Speicher), der manchmal langsamer ist als der Zugriff auf ein einfaches Member ohne Zeiger. Der d-Pointer wird in den Bibliotheken Qt [7] und KDE stark verwendet.
No comments:
Post a Comment