Cheshire Cats: Information Hiding für Paranoide

Das unter objektorientierten Menschen so beliebte ,,information hiding`` ist in C++ ähnlich umgesetzt wie in anderen objektorientierten Sprachen auch: man deklariert Teile einer Klasse als public, protected und private (und -anders als in Java- auch entsprechend, von welchen Klassen man ableitet). Damit gibt der Ersteller einer klasse vor, was nur in der Klasse benutzt werden darf und was der Benutzer beim Ableiten oder Instanziieren verwenden darf. Eine so erteilte Zugriffsbeschränkung wird zwar als information hiding bezeichnet, ist aber in Wirklichkeit gar kein Verstecken von Informationen: der Benutzer hat ja offensichtlich Lesezugriff auf die von ihm mit #include eingebundenen Headerdateien, in denen die private- und protected-Elemente der Klasse ja alle aufgeführt sind.

Auch wenn die so realisierte Zugriffsbeschränkung hinreichend ist, um sauberes Programmieren zu fördern, ist es gelegentlich noch nicht ausreichend.

Beispielsweise möchte ein Anbieter einer kommerziellen Bibliothek, der viel Entwicklungsaufwand in das Design steckte, sicher nicht seinen Konkurrenten die Arbeit beim Nachbau erleichtern, indem er alle Datenelemente und intern verwendeten Methoden in der Headerdatei auflistet; am besten noch gut kommentiert.

Die Definition der Methoden (also der wirklich ausgeführte Code) ist recht leicht vor dem Benutzer zu verstecken, indem in der Klasse nur die Deklarationen aufgeführt werden, und die Definitionen dagegen außerhalb der Klasse in einem eigenen Quelltext. Letzterer wird für das jeweilige Zielsystem kompiliert und dem Anwender nur als Objektdatei ausgeliefert.

Aber auch die Deklaration der Methoden und der Datenelemente ist bereits recht informativ.

Was der Anwender wirklich braucht, ist ja nur der öffentliche Teil (public) der Schnittstelle (und falls er Ableitungen der Klasse erstellen soll, auch noch den protected-Teil, was im folgenden aber ignoriert wird; es ist analog zu behandeln).

Um jetzt alles zu verbergen, was der Benutzer nicht unbedingt braucht, gibt es einen Mechanismus, der gelegentlich als Cheshire Cats bezeichnet wird:

Der Ersteller einer Klasse (beispielsweise A) baut in Wirklichkeit zwei Klassen:

  1. eine interne Klasse A_intern mit der vollen Funktionalität in einem eigenen Quelltext A_intern.cpp und einer eigenen Deklarationsdatei A_intern.h. Diese Klasse wird dem Anwender nur kompiliert zur Verfügung gestellt; weder der Quelltext A_intern.cpp noch die Deklarationen in A_intern.h werden aus der Hand gegeben.
  2. Eine weitere Klasse A, mit der der Anwender letztlich arbeitet, wird ebenfalls in einem Quelltext (A.cpp) und einer Headerdatei A.h erstellt.

    Letztere wird dem Benutzer zur Verfügung gestellt, und enthält ausschließlich öffentliche Elemente und Methoden (oder auch protected, falls der Anwender ableiten darf). Zudem ist in der Klasse eine Referenz auf ein Element der geheimen Klasse A eingefügt, und im Konstruktor wird ein solches Element allokiert und im Destruktor wieder freigegeben. Dazu muß der Compiler beim Übersetzen der Anwenderprogramme nicht mehr wissen, als daß es eine Klasse mit dem Namen A_intern gibt.

    Die Implementation der Klasse A in der Datei A.cpp wird dem Anwender nicht im Quelltext zur Verfügung gestellt, sondern ebenfalls nur als kompilierte Objektdatei.

    Neben dem beschriebenen Allokieren und Freigeben des Elements der Klasse A_intern (was sowohl in der Headerdatei als auch in der Definitionsdatei erfolgen kann) enthält diese Klasse nur alle öffentlichen Methoden aus der geheim zu haltenden internen Klasse. Diese Methoden rufen jeweils nur die gleichnamige Methode aus der internen Klasse auf und reichen dabei ihre Parameter und die Funktionsergebnisse durch.

Was der Anwender also bekommt, ist nur noch eine Headerdatei A.h mit dem öffentlichen Teil (für den Compiler ebenso wie als Dokumentation, soweit diese nicht extern erfolgt), sowie die Kompilate der beiden Klassen.

Zum Begriff ,,Cheshire Cats`` habe ich zwei Stellen im Internet gefunden, mit denen die Herkunft aber auch nicht so recht klar wird:

AnyWare@Wachtler.de