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