On 2016-08-10 16:47, Tony Whyman wrote: > You are explicitly freeing MyClass. My point is that with reference > counted interfaces and in the example I posted, you shouldn't have to > explicitly free the delegated interface. It should be freed > automatically as soon as it goes out of scope.
Let me explain with a slightly modified example. NOTE: I get the exact same behaviour under FPC 2.6.4 and under Delphi 7. The reason I [must] free the TMyClass instance is because it is a TObject descendant. Obviously I can query the interface from that instance and don't have to free anything interface related. In the second test project I create a TMyInterface instance, which is a TInterfaceObject descendant. I store it directly to a interface reference variable, and then use the interface as needed. I don't need to free anything here, because TInterfaceObject is reference counted and will free itself once it goes out of scope. I think you are getting confused between TObject and TInterfaceObject instances, and what is required from both. =====================[ test2.pas ]=========================== program test2; {$mode objfpc}{$H+} {$interfaces com} { Delegating to an interface-type property } uses Classes, SysUtils; type IMyInterface = interface ['{9CF79E28-6527-11E6-9A7E-C86000E37EB0}'] procedure P1; procedure P2; end; TMyInterface = class(TInterfacedObject, IMyInterface) private procedure P1; procedure P2; public constructor Create; destructor Destroy; override; end; TMyClass = class(TObject, IMyInterface) FMyInterface: IMyInterface; property MyInterface: IMyInterface read FMyInterface implements IMyInterface; public constructor Create; destructor Destroy; override; end; procedure TMyInterface.P1; begin writeln('TMyInterface.P1'); end; procedure TMyInterface.P2; begin writeln('TMyInterface.P2'); end; constructor TMyInterface.Create; begin writeln('Creating ',ClassName); end; destructor TMyInterface.Destroy; begin writeln('Destroying ',ClassName); inherited Destroy; end; { TMyClass } constructor TMyClass.Create; begin writeln('Creating ',ClassName); FMyInterface := TMyInterface.Create; end; destructor TMyClass.Destroy; begin writeln('Destroying ',ClassName); inherited Destroy; end; procedure Test1; var MyClass: TMyClass; MyInterface: IMyInterface; begin MyInterface := nil; MyClass := TMyClass.Create; if Supports(MyClass, IMyInterface, MyInterface) then begin MyInterface.P1; MyInterface.P2; end; MyClass.Free; // because TMyClass is a TObject descendant end; procedure Test2; var MyInterface: IMyInterface; begin MyInterface := TMyInterface.Create; MyInterface.P1; MyInterface.P2; MyInterface := nil; // optional end; begin Test1; writeln('========================='); Test2; end. ===================[ end ]=================================== And the output of the program gives this.... $ ./test2.exe Creating TMyClass Creating TMyInterface TMyInterface.P1 TMyInterface.P2 Destroying TMyClass Destroying TMyInterface ========================= Creating TMyInterface TMyInterface.P1 TMyInterface.P2 Destroying TMyInterface which is expected and correct. Regards, Graeme -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal