Unterschiede zwischen interface_cast und static_cast

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Neue Typumwandlung

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;
 }

Siehe auch