Différences entre interface_cast et static_cast

De RAD Studio
Aller à : navigation, rechercher

Remonter à Nouveau style de transtypage


Vue globale comparative de interface_cast et static_cast

interface_cast est une fonction template définie dans l'unité System, utilisée pour effectuer un transtypage entre différentes interfaces, ou entre les interfaces et les objets. static_cast est un mot clé C++ standard utilisé pour effectuer des conversions de type à la compilation (pas à l'exécution, comme interface_cast et dynamic_cast).

interface_cast appelle QueryInterface pour obtenir l'interface cible. Le transtypage est réalisé à l'exécution et il peut échouer si l'objet sous-jacent ne supporte pas l'interface cible. Si un static_cast échoue, le code n'est pas compilé (l'erreur E2031 est émise).

interface_cast est ciblée pour les interfaces de style COM implémentées par les classes Delphi (classes dérivées TObject). Vous devez utiliser interface_cast avec des interfaces de style COM afin de garantir une gestion correcte du cycle de vie. static_cast ne participe pas dans l'approche _AddRef/_Release de la gestion du cycle de vie.

Obtention d'une instance d'interface avec interface_cast

Le code suivant représente le code source Delphi qui est compilé dans un package (fichier bpl). Il contient l'implémentation d'une classe et d'une 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.

Le code suivant représente une application console C++Builder qui utilise la classe et l'interface définies précédemment dans Delphi. Le projet C++Builder est construit avec le package issu du projet Delphi (voir le code précédent).

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

Obtention d'une instance d'interface avec static_cast (cas particulier)

Il est possible d'utiliser static_cast pour transtyper des interfaces. Mais vous pouvez le faire dans des situations très particulières :

  • Le compilateur C++ peut "voir" la hiérarchie spécifique. La hiérarchie des classes écrites dans Delphi qui implémentent des interfaces n'est pas visible par le compilateur C++.
  • _AddRef est appelée pour les nouvelles instances d'interface.

L'exemple suivant illustre ce cas particulier (où static_cast peut être utilisé pour obtenir une instance d'interface en toute sécurité)

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

Voir aussi