In Delphi können Klassenmethoden aufgerufen werden, ohne zunächst eine Instanz der Klasse zu erzeugen. Dies ist ähnlich wie der Aufruf statischer Methoden in C++. Aber in C++ ist es nicht möglich, wie in Delphi Klassen Variablen als Werte zuzuweisen und anschließend Instanzen der Klassen zu erzeugen, indem virtuelle Klassenmethoden dieser Variblen aufgerufen werden.
Für den C++Builder gibt es die __classid Funktion als spezielle Erweiterung, um solche Klassenreferenzen zu erhalten. Lediglich eine kleine Delphi Unit muss zu einem C++Builder Projekt hinzugefügt werden, um aus solchen Klassenreferenzen Instanzen der Klassen zu erzeugen.
Mit anderen Compilern das Gleiche zu erreichen ist sehr viel schwieriger.
So wie für den C++Builder die Klasse TMetaClass definiert ist, so wird sie auch für andere Compiler definiert. Außerdem wird der TClass Typ als Zeiger auf TMetaClass definiert:
typedef TMetaClass* TClass
TMetaClass ist der Klassenreferenztyp für TObject und ist die Basisklasse für alle Klassenreferenztypen aller anderen Klassen. Diese Klassenreferenzen sind definiert als Instanzen einer generischen ClassRef-Klasse:
templateclass ClassRef
wobei der Template-Parameter für die originale Klasse steht. Aus diese Weise gibt es für eine Hierarchie von Klassen, die voneinander abgeleitet sind, eine parallele Hierarchie von Klassenreferenzen. Die Klassenreferenzen sind als Singletons implementiert und werden nur erzeugt, wenn sie gebraucht werden. Die exakte Definition der ClassRef-Klasse ist trickreich und nur möglich, weil Delphi2Cpp 2.x zusätzlichen Hilfcode in jede Klassendeklaration schreibt.
Der folgende Code demonstriert, wie eine kleine Klassen-Factory unter Benutzung von Klassenreferenzen von Delphi nach C++ konvertiert wird.
type TBase = class public function GetName: String; virtual; end;
TBaseClass = class of TBase;
TDerived = class(TBase) public function GetName: String; override; end;
TDerivedClass = class of TDerived;
implementation
function make(Base: TBaseClass): TBase; begin result := Base.Create; end;
function testTactory: boolean; var s : String; p : TBase; begin p := make(TDerived1); result := p.GetName = 'TDerived1'; end;
->
class TBase : public System::TObject { public: typedef System::ClassRefClassRefType; ClassRefType* ClassType() const {return System::class_id ();} TBase* Create() {return new TBase();} static TBase* SCreate() {return new TBase();} System::String ClassName() {return L"TBase";} static System::String SClassName() {return L"TBase";} TBase(); };
typedef TBase::ClassRefType TBaseClass;
class TDerived : public TBase { public: typedef System::ClassRefClassRefType; ClassRefType* ClassType() const {return System::class_id ();} TDerived* Create() {return new TDerived();} static TDerived* SCreate() {return new TDerived1();} System::String ClassName() {return L"TDerived";} static System::String SClassName() {return L"TDerived";} TDerived(); };
typedef TDerived::ClassRefType TDerivedClass;
TBase* make(TBaseClass* Base) { TBase* result = nullptr; result = Base->Create(); return result; }
bool testfactory() { bool result = false; String s; TBase* P = nullptr; P = make(class_id()); result = P->GetName() == L"TDerived"; return result; }
Der zentrale Punkt in diesem Code ist der Aufruf der class_id-Funktion:
P = make(class_id());
Die class_id-Funktion erfüllt den gleichen Zweck wie die __classid-Funktion im C++Builder Code: sie liefert die Klassenreferenzen, im Beispiel, die Klassenreferenz zum TDerived-Typ.
english
Letzte Neuigkeiten |
08/26/24
Delphi2Cpp 2.4: Updated to RAD Studio 12.1 Athens [more...] |
29.01.24
Aurora2Cpp: Delphi 7 Konverter [more...] |
[aus Fallstudie...] "Eine Meisterleistung -- Delphi2Cpp hat alle meine Erwartungen weit übertroffen." Tony Hürlimann
virtual-optima
29.08.2011
|
"Ich muss mich nochmal für deinen Einsatz und die Qualität deiner Arbeit bedanken, das ist absolut überdurchschnittlich ..." Gerald Ebner
Significant Software
22.01.2010
|
Diese Homepage ist aus einfachen Texten mit [Minimal Website ]generiert.
|
Minimal Website ist mit Hilfe des TextTransformers hergestellt.
|
Der TextTransformer ist gemacht mit dem Borland
CBuilder
|