Objektidentität und -instantiierung
Nach oben zu Sprachunterstützung für die VCL (C++)
In C++ ist eine Instanz einer Klasse ein konkretes Objekt. Dieses Objekt kann direkt manipuliert werden, oder es kann darauf indirekt über eine Referenz oder einen Zeiger zugegriffen werden. Beispielsweise sind für eine gegebene C++-Klasse CPP_class mit einem Konstruktor, der keine Argumente aufnimmt, alle folgenden Instanzvariablen dieser Klasse gültig:
CPP_class by_value;// ein Objekt des Typs CPP_class CPP_class& ref = by_value;// eine Referenz auf das Objekt per Wert CPP_class* ptr = new CPP_class();// ein Zeiger auf ein Objekt des Typs CPP_class
Im Gegensatz dazu verweist in Object Pascal eine Variable des Typs Objekt immer indirekt auf das Objekt. Der Speicher für alle Objekte wird dynamisch zugewiesen. Beispiel einer gegebenen Object Pascal-Klasse OP_class:
ref: OP_class ; ref := OP_class.Create ; ref ist eine “Referenz” auf ein Objekt des Typs OP_class. Der entsprechende C++Builder-Code würde folgendermaßen aussehen: OP_class* ref = new OP_class;
Inhaltsverzeichnis |
Unterscheiden von C++- und Object Pascal-Referenzen
In der Dokumentation wird eine Object Pascal-Klasseninstanzvariable häufig als Referenz bezeichnet, ihr Verhalten aber als das eines Zeigers beschrieben, und zwar, weil sie Eigenschaften von beiden beinhaltet. Eine Object Pascal-Objektreferenz entspricht einem C++-Zeiger mit den folgenden Ausnahmen:
- Eine Object Pascal-Referenz ist implizit dereferenziert (in diesem Fall verhält sie sich eher wie eine C++-Referenz).
- Eine Object Pascal-Referenz hat keine Zeigerarithmetik als definierte Operation.
Object Pascal-Referenzen und C++-Referenzen verfügen auch über Ähnlichkeiten und Unterschiede. Referenzen sind in beiden Sprachen implizit dereferenziert, aber:
- Eine Object Pascal-Referenz kann neu gebunden werden, eine C++-Referenz nicht.
- Eine Object Pascal-Referenz kann nil sein, eine C++-Referenz muss auf ein gültiges Objekt verweisen.
Einige der für das VCL-Framework getroffenen Designentscheidungen basieren auf der Verwendung dieser Art von Instanzvariable. Zeiger sind das C++-Sprachkonstrukt, das Object Pascal-Referenzen am nächsten kommen. Deshalb werden fast alle VCL-Objektbezeichner in C++Builder in C++-Zeiger übersetzt.
Hinweis: Der Object Pascal-Parametertyp var entspricht am ehesten einer C++-Referenz.
Kopieren von Objekten
Im Gegensatz zu C++ bietet Object Pascal keine integrierte Compiler-Unterstützung zum Kopieren eines Objekts. Dieser Abschnitt beschreibt die Auswirkung dieses Unterschieds auf Zuweisungsoperatoren und Kopierkonstruktoren für Klassen im VCL-Stil.
Zuweisungsoperatoren
Der Object Pascal-Zuweisungsoperator (:=) ist kein Klassenzuweisungsoperator (operator=()). Der Zuweisungsoperator kopiert die Referenz, nicht das Objekt. Im folgenden Code verweisen B und C auf dasselbe Objekt:
B, C: TButton ; B:= TButton.Create(ownerCtrl) ; C:= B ;
In C++Builder würde dieses Beispiel folgendermaßen aussehen:
TButton *B = NULL ; TButton *C = NULL ; B = new TButton(ownerCtrl) ; C = B;// kopiert den Zeiger, nicht das Objekt
Klassen im VCL-Stil folgen in C++Builder den Object Pascal-Sprachregeln für Zuweisungsoperatoren. Das heißt, dass im folgenden Code Zuweisungen zwischen dereferenzierten Zeigern nicht gültig sind, weil sie versuchen, das Objekt und nicht den Zeiger zu kopieren:
TVCLStyleClass *p = new TVCLStyleClass ; TVCLStyleClass *q = new TVCLStyleClass ; *p = *q;// nicht zulässig für Klassenobjekte im VCL-Stil
Hinweis: Bei Klassen im VCL-Stil kann die C++-Syntax zum Binden einer Referenz verwendet werden. Beispielsweise ist der folgende Code zulässig:
TVCLStyleClass *ptr = new TVCLStyleClass ; TVCLStyleClass &ref = *ptr;// OK für Klassen im VCL-Stil
Obwohl das nicht der Verwendung eines Zuweisungsoperators entspricht, ist die Syntax doch ähnlich genug, um hier aus Klarstellungs- und Vergleichsgründen erwähnt zu werden.
Kopierkonstruktoren
Object Pascal hat keine integrierten Kopierkonstruktoren. Folglich haben auch Klassen im VCL-Stil in C++Builder keine integrierten Kopierkonstruktoren. Im folgenden Beispielcode wird versucht, einen TButton-Zeiger mithilfe eines Kopierkonstruktors zu erstellen:
TButton *B = new TButton(ownerCtrl) ; TButton *C = new TButton(*B);// nicht zulässig für Klassenobjekte im VCL-Stil
Schreiben Sie keinen Quelltext, der von einem integrierten Kopierkonstruktor für VCL-Klassen abhängig ist. Um in C++Builder eine Kopie eines Klassenobjekts im VCL-Stil zu erstellen, können Sie eine Member-Funktion schreiben, die das Objekt kopiert. Eine Alternative bieten Nachkommen der VCL-Klasse TPersistent, die die Methode Assign überschreiben können, um Daten von einem Objekt in ein anderes zu kopieren. Dieses Vorgehen wird beispielsweise in Grafikklassen, wie TBitmap und TIcon, angewandt, die Ressourcenbilder enthalten. Letztlich kann die Art und Weise, wie ein Objekt kopiert wird, durch den Programmierer (Komponentenentwickler) bestimmt werden; denken Sie aber daran, dass einige der C++-Standardkopiermethoden für Klassen im VCL-Stil nicht zur Verfügung stehen.
Objekte als Funktionsargumente
Wie bereits weiter oben erwähnt, sind Instanzvariablen in C++ und in Object Pascal nicht identisch. Bedenken Sie dies, wenn Sie Objekte als Argumente an Funktionen übergeben. In C++ können Objekte entweder per Wert, per Referenz oder per Zeiger an Funktionen übergeben werden. Wenn in Object Pascal ein Objekt per Wert an eine Funktion übergeben wird, dann ist das Objektargument bereits eine Referenz auf das Objekt. Daher wird tatsächlich die Referenz per Wert übergeben nicht das eigentliche Objekt. In Object Pascal gibt es kein Äquivalent zur Übergabe des tatsächlichen Objekts per Wert wie in C++. Objekte im VCL-Stil, die an Funktionen übergeben werden, folgen den Object Pascal-Regeln.