[fpc-pascal] A serious Memleak using delegates/implements (was: Delegate Interface class does not seem to be referenced counted)

stdreamer stdreamer at freemail.gr
Fri Oct 7 13:29:37 CEST 2016


On 07/10/2016 13:30 μμ, Tony Whyman wrote:
> On 07/10/16 11:08, stdreamer wrote:
>> I see no rabbit hole or any other problem in the code posted so far
>> except perhaps lack of proper clean up which might be intentional.
> A Rabbit Hole is not the same as a bug and my point is not that
> "interface delegation" does not work, it is that it is counter-intuitive
> and poorly documented to the point of undocumented. Your introduction of
> TContainedObject is just another example of missing information.

No! Delegation is a mechanism, when used, you have to know exactly how 
it works. Delegation is only used to minimize code instead of writing a 
bunch of procedures that call the contained object's methods. That's it 
and nothing more.

The contained object is something else that happens to be used in this 
example. Here is an other delegation with out a contained interface.

interface
   TMyInteger = Class;

   IValue = interface
   ['{72D8B44F-5834-425D-AB3A-45785E94E2E4}']
     function AsString:string;
   end;

   IMyInterface = interface
    ['{5E04F587-E4A0-42A7-850C-74C882BB5958}']
    procedure DoSomething;
   end;

   //tmyvalue can inherit from tContainedobject
   //for simplification.

   TMyValue = class(TInterfacedObject, IValue)
   private
     FSource :TMyInteger;
   public
     function AsString:String;
     constructor Create(aSource:TMyObject);
   end;
   //IValue must be part of TMyObject not a simple property.

   { TMyObject }

   { TMyInteger }

   TMyInteger = class(TInterfacedObject, IMyInterface, IValue)
   private
     FMyValue :variant;
     function GetValue :IValue;
   private
     property MyValue :IValue read GetValue implements IValue;
   public
     procedure DoSomething;
   end;

implementation

function TMyInteger.GetValue :IValue;
begin
   Result := TMyValue.Create(Self);
end;

procedure TMyInteger.DoSomething;
begin

end;

function TMyValue.AsString :String;
begin
   result := ToString(FSource.FMyValue);
end;

constructor TMyValue.Create(aSource :TMyInteger);
begin
   inherited;
   FSource := aSource;
end;

>
> Reference Counted interfaces must be easy to use and should not require
> the user to have advanced knowledge of how they work.If that last point
> is true then all the that nay-sayers that argue against reference
> counted interfaces have their point made for them.
>
Erm knifes are easy to use as well but cutting your self with one is 
your problem to solve.

The point is that you are trying to equate delegation with contained 
objects/interfaces and that is not what delegates are about. Delegation 
has nothing to do with the underlined mechanism you choose to use.

Having said that, I have to agree with you that contained objects are 
the most common supporting mechanism for a delegation and probably the 
most logical to use.

As I said I do not see a rabbit hole that it was created by the compiler 
or the language nor I think that the compiler should constrain you to 
one mechanism.





More information about the fpc-pascal mailing list