Unterschiede zwischen interface_cast und static_cast
Nach oben zu Neue Typumwandlung
Inhaltsverzeichnis |
Vergleichende Übersicht über interface_cast und static_cast
interface_cast ist eine in der Unit System definierte template-Funktion, mit der die Typen verschiedener Interfaces oder die Typen von Interfaces und Objekten umgewandelt werden. static_cast ist ein C++-Standardschlüsselwort, mit dem Typumwandlungen beim Compilieren (nicht zur Laufzeit, wie interface_cast und dynamic_cast) durchgeführt werden.
interface_cast ruft zur Ermittlung des Ziel-Interface QueryInterface auf. Die Umwandlung wird zur Laufzeit durchgeführt und kann fehlschlagen, wenn das zugrundeliegende Objekt das Ziel-Interface nicht unterstützt. Wenn static_cast fehlschlägt, dann wird der Code nicht compiliert (der Fehler E2031 wird ausgegeben).
interface_cast ist für Interfaces im COM-Stil vorgesehen, die von Delphi-Klassen (von TObject abgeleitete Klassen) implementiert werden. Sie sollten interface_cast mit Interfaces im COM-Stil verwenden, um eine korrekte Lebensdauerverwaltung sicherzustellen. (static_cast ist nicht Teil des _AddRef/_Release-Verfahrens zur Lebensdauerverwaltung.)
Ermitteln einer Interface-Instanz mit interface_cast
Das folgende Codelisting stellt Delphi-Quellcode dar, der in ein Package (bpl-Datei) compiliert wird. Er enthält die Implementierung einer Klasse und eines Interface.
unit MyUnit; interface type IMyInterface = interface(IUnknown) ['{D982FC08-5280-44FC-BE3B-BFD951E8BA5C}'] procedure Welcome; end; TMyInterface = class(TInterfacedObject, IMyInterface) public procedure Welcome; end; implementation procedure TMyInterface.Welcome; begin WriteLn('Welcome!'); end; end.
Das folgende Codelisting stellt eine C++Builder-Konsolenanwendung dar, die die zuvor in Delphi definierte Klasse und das Interface verwendet. Das C++Builder-Projekt wird mit dem Package erzeugt, das als Ergebnis des Delphi-Projekts (siehe vorheriges Listing) erstellt wurde.
#include <System.hpp> #pragma hdrstop #include <tchar.h> //--------------------------------------------------------------------------- #include <MyUnit.hpp> #pragma argsused int _tmain(int argc, _TCHAR* argv[]) { TMyInterface *inst = new TMyInterface(); _di_IMyInterface intf = interface_cast<Myunit::IMyInterface>(inst); // static_cast cannot be used -- the cast cannot be done at compile time if (intf) { intf->Welcome(); } return 0; }
Ermitteln einer Interface-Instanz mit static_cast (Sonderfall)
Zur Typumwandlung von Interfaces kann auch static_cast verwendet werden. Dies ist aber nur in sehr speziellen Situationen möglich:
- Der C++-Compiler kann die spezifische Hierarchie "sehen". (Die Hierarchie von in Delphi geschriebenen Klassen, die Interfaces implementieren, ist für den C++-Compiler nicht sichtbar.)
- _AddRef wird für die neuen Interface-Instanzen aufgerufen.
Das folgende Beispiel zeigt einen solchen Sonderfall (in dem mit static_cast eine Interface-Instanz sicher abgerufen werden kann):
#include <iostream> #include <tchar.h> #include <System.hpp> // --------------------------------------------------------------------------- __interface __declspec(uuid("{D982FC08-5280-44FC-BE3B-BFD951E8BA5C}")) IMyInterface : public IInterface { public: virtual void __fastcall Welcome() = 0; }; typedef System::DelphiInterface<IMyInterface>_di_IMyInterface; class TMyInterface : public TCppInterfacedObject<IMyInterface> { public: void __fastcall Welcome() { std::cout << "Welcome!" << std::endl; } }; // --------------------------------------------------------------------------- int _tmain(int argc, _TCHAR* argv[]) { _di_IMyInterface intf(static_cast<IMyInterface*>(new TMyInterface())); intf->Welcome(); return 0; }