[fpc-pascal] Question about interfaces and patch

Michael Van Canneyt michael.vancanneyt at wisa.be
Thu Mar 24 09:06:46 CET 2005



On Thu, 24 Mar 2005 ml at brainwashers.org wrote:

> Quoting Michael Van Canneyt <michael.vancanneyt at wisa.be>:
>
>>
>>
>> On Wed, 23 Mar 2005 ml at brainwashers.org wrote:
>>
>>> Quoting Marco van de Voort <marcov at stack.nl>:
>>>
>>>>> On Tue, 22 Mar 2005, ml wrote:
>>>>>> // than one interface
>>>>>>  a := (object as IA); // correct
>>>>>>  b := (object as IB); // returns pointer to the first interface
>>> vmt=IA
>>>>>>  c := (object as IC); // returns pointer to the first interface
>>> vmt=IA
>>>>>> // there's no way to do again it's like direct call to exception
>>>>>>  obj := a; // returns pointer(obj) + 12 ???
>>>>>
>>>>> This is nonsense. You cannot assign an interface to a class.
>>>>> A class IMPLEMENTS an interface, it is not an interface.
>>>
>>> Ok, its nonsense. I said it already works with my patch, but I guess you
>>> know it better. So my example down there doesn't work (with patch). You
>>> should know.
>>> I (; can't ;) transfer from one interface to other back to object and to
>>> 3rd interface. I just imagine my results.
>>
>> Tell me, what is
>>
>>    obj := a;
>>
>> supposed to DO ? A class has a set of methods. Some of these methods form
>> the VMT of an interface. What your code does, is say
>> "don't use your VMT methods, use these instead' ?
>
> Yes, exactly. I even provided test example at the bottom of my previous message,
> where I transfered from class to IA, back to class and then to ID. And called
> ID.D; And it just works (this is also nice start for blind properties
> implementation, which now also became possible, since original vmt is now visible)
>
> But, It should be used as
>
> if (TObject(a).InheritedFrom(TSomeClass)) then begin
>  obj := TSomeClass(a); // note that here obj is declared as TSomeClass
>  // now safely use as this vmt
> end;
>
> if SupportsInterface(TObject(a), IB) then begin
>  ibvar := a;  // declared ibvar: IB
>  // now safely use as this vmt
> end;
>
> in perfect world "is" would return InheritedFrom or SupportsInterface result and
> not actual class check, if true then all needed operations are satisfied.

I can understand that 'is' should be able to check interfaces; this is a
useful patch.

I also understand what your code should do.

BUT I see some flaws in your design.

  IA = Interface
    procedure InitF;
  end;


  TA = class(TObject,IA)
    F : TList;
    Procedure InitF;
    Procedure B;
  end;

  Procedure TA.InitF;

  begin
    F:=Tlist.Create;
  end;

  Procedure TA.B;

  begin
    F.Add(SomePointer);
  end;


Var
   A : TA;
   C : IA;

begin
   A:=TA.Create;
   C:=SomeIA;    // Get an IA interface from somewhere.
   A:=C;
   A.InitF;      // <<--- Which InitF should be used ?
   A.B;          // Crash or not ?
end;

If TA.InitF is used, then B runs OK, but then A:=C has no meaning at all.
If the InitF from C is used, then F will not be initialized, and B will
fail.

Michael.




More information about the fpc-pascal mailing list