Recent

Author Topic: How to use interfaces  (Read 4798 times)

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2032
  • Former Delphi 1-7, 10.2 user
How to use interfaces
« on: October 05, 2021, 12:42:04 am »
The Wiki has a demo program in the article How to use interfaces to which someone has recently added:

Quote
this code contains memory leaks and incorrect use of interfaces. Please pay attention to this.

Could someone who understands the use of interfaces take a look? If it is incorrect it needs to be either fixed or deleted.

Warfley

  • Hero Member
  • *****
  • Posts: 2049
Re: How to use interfaces
« Reply #1 on: October 05, 2021, 03:19:26 am »
First of all, yes it produces a memory leak, which can be verified by compiling with the heaptrc unit.

The reason for this is the following: GetInterface returns not an interface reference of R, but of Hook, as it is defined in:
Code: Pascal  [Select][+][-]
  1.     //Here we tell the compiler that our class
  2.     //interface implementation is provided by
  3.     //a member field wich we initialize in this case
  4.     //on the constructor
  5.     property Hook: ITestInterface read FHook implements ITestInterface;
Therefore R will not be handled as an interface reference which circumvents the reference counting of it. Therefore it will not get freed.

Only references of the hook will be incresed and decreased by the use of the variable I, but as R still holds a reference, it will not drop to 0 and therefore not freed.
This causes two memory leaks, first R doesn't get freed and second the Hook of R doesn't get freed.

Solution: 1. remove the destructor of TRealClass, this is not needed as reference counting does the job.
2. Add an R.Free to the end of the program.


That said, IMHO this example is pretty bad and probably causes more confusion than helping anyone (the existance of this thread proof of that), this probably needs a rework and/or some explaination. There is no reason why TRealClass actually implements the TBaseObject, this let it seem like it itself provides the interface functionality while the whole example is to show that you can delegate that to a member/property. This makes this very confusing.

Generally speaking, an article called "How To Use Interfaces" could use more than one example, especially if that example only showcases a very corner case of interface usage (i would say delegating the interface implementation to a property is not really the main use case for interfaces), but could take more examples and maybe some explaination.
IMHO this article does more harm than good, as it is very confusing (and also simply broken), while not really giving any insight on how to use interfaces. It probably just scares people away of using interfaces rather than helping to understand them
« Last Edit: October 05, 2021, 03:26:46 am by Warfley »

zamtmn

  • Hero Member
  • *****
  • Posts: 683
Re: How to use interfaces
« Reply #2 on: October 05, 2021, 06:15:35 am »
>>to which someone has recently added:
I added that. I was dealing with interfaces and this example put me confused.
But I don't know how to make simple visual examples, so I did this.

>>2. Add an R.Free to the end of the program.
no, this causes av in THook(FHook).Free;

Warfley

  • Hero Member
  • *****
  • Posts: 2049
Re: How to use interfaces
« Reply #3 on: October 05, 2021, 12:53:38 pm »
>>2. Add an R.Free to the end of the program.
no, this causes av in THook(FHook).Free;
Thats what Step 1 is for, when removing the destructor this removes the free of the hook, which will then be taken care of by the ref counter

ccrause

  • Hero Member
  • *****
  • Posts: 1105
Re: How to use interfaces
« Reply #4 on: October 05, 2021, 03:23:13 pm »
Generally speaking, an article called "How To Use Interfaces" could use more than one example, especially if that example only showcases a very corner case of interface usage (i would say delegating the interface implementation to a property is not really the main use case for interfaces), but could take more examples and maybe some explaination.
IMHO this article does more harm than good, as it is very confusing (and also simply broken), while not really giving any insight on how to use interfaces. It probably just scares people away of using interfaces rather than helping to understand them
I agree, this page should state clearly that the focus is interface delegation.  It is not a general overview of interfaces, there are other wiki pages that give a more general overview of interfaces.

Thaddy

  • Hero Member
  • *****
  • Posts: 18938
  • Glad to be alive.
Re: How to use interfaces
« Reply #5 on: October 05, 2021, 04:52:41 pm »
Ouch... Who wrote that? >:D >:D >:D >:D
I will correct it. e.g.
Code: Pascal  [Select][+][-]
  1. program interfacesygenerics;
  2. {$mode objfpc}{$H+}
  3. type
  4.   ITestInterface = interface
  5.     ['{3FB19775-F5FA-464C-B10C-D8137D742088}']
  6.     procedure DoSomething;
  7.     procedure DoItAll;
  8.   end;
  9.  
  10.   TBaseObject = class(TInterfacedObject,ITestInterface)
  11.     procedure DoSomething;
  12.     procedure DoItAll;
  13.   end;
  14.  
  15.   TderivedObect = class(TBaseObject,ITestInterface)
  16.     procedure DoSomething;
  17.     procedure DoItAll;
  18.   end;
  19.  
  20.   procedure TBaseObject.DoSomething;
  21.   begin
  22.     Writeln('TBaseObject DoSomething !');
  23.   end;
  24.  
  25.   procedure TBaseObject.DoItAll;
  26.   begin
  27.     Writeln('TBaseObject DoItAll !');
  28.   end;
  29.   procedure TderivedObect.DoSomething;
  30.   begin
  31.     Writeln('TderivedObect DoSomething !');
  32.   end;
  33.  
  34.   procedure TderivedObect.DoItAll;
  35.   begin
  36.     Writeln('TderivedObect DoItAll !');
  37.   end;
  38.  
  39. var
  40.   I: ITestInterface;
  41. begin
  42.   Writeln('Using regular interfaces');
  43.   I := TderivedObect.Create as ITestInterface;
  44.   if I <> nil then
  45.     Writeln('Got interface OK. Calling it');
  46.   I.DoSomething;
  47.   I.DoItAll;
  48. end.
The rest of the code was complete and utter nonsense, so it might be better to remove it completely.
At least now the code works and does not leak anymore. Two minutes...
« Last Edit: October 05, 2021, 05:36:46 pm by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: How to use interfaces
« Reply #6 on: October 05, 2021, 06:23:27 pm »
That page was written in 2009.

Thaddy

  • Hero Member
  • *****
  • Posts: 18938
  • Glad to be alive.
Re: How to use interfaces
« Reply #7 on: October 05, 2021, 06:32:18 pm »
That page was written in 2009.
In 2009 the rules were the same. I corrected it (somewhat). At least no leaks and a similar intention. Still demands further attention. (COM vs CORBA).
You can do a lot of DIY on that entry, but at least part of it is repaired.
« Last Edit: October 05, 2021, 07:13:28 pm by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

Warfley

  • Hero Member
  • *****
  • Posts: 2049
Re: How to use interfaces
« Reply #8 on: October 05, 2021, 07:12:59 pm »
Well your example (even though I think it is more useful) does not show the same thing as the one in the wiki article.  In the wiki it shows how to delegate the interface functionality to a member, your just shows how to use interfaces "normally".

Thaddy

  • Hero Member
  • *****
  • Posts: 18938
  • Glad to be alive.
Re: How to use interfaces
« Reply #9 on: October 05, 2021, 07:16:08 pm »
Agree, hence I added DIY. A two minutes edit can not provide the spectrum.
I will see if I can come up with a simple example of proper delegation.

(My first concern was leaks)
« Last Edit: October 05, 2021, 07:18:51 pm by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

PierceNg

  • Sr. Member
  • ****
  • Posts: 434
    • SamadhiWeb
Re: How to use interfaces
« Reply #10 on: October 06, 2021, 04:46:47 am »
Agree, hence I added DIY. A two minutes edit can not provide the spectrum.
I will see if I can come up with a simple example of proper delegation.

(My first concern was leaks)

How about an example where the two classes implementing the interface are not related to each other? I think that'll demonstrate the value of interfaces even better than having TDerivedObject subclass TBaseObject.

Thaddy

  • Hero Member
  • *****
  • Posts: 18938
  • Glad to be alive.
Re: How to use interfaces
« Reply #11 on: October 06, 2021, 07:59:20 am »
Will do. Adapted example
« Last Edit: October 06, 2021, 09:25:34 am by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

Zvoni

  • Hero Member
  • *****
  • Posts: 3349
Re: How to use interfaces
« Reply #12 on: October 06, 2021, 11:14:24 am »
Will do. Adapted example
Since you're cleaning up the Wiki, would you mind take a look at this article?
https://wiki.lazarus.freepascal.org/Understanding_Interfaces

IMO, this Article shed's no light on the power of interfaces (especially the last code-sample. Basically you could remove the IRecycable-Type, change the class-def of the other two classes - No TInterfacedObject etc., and the code would still work)
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

devEric69

  • Hero Member
  • *****
  • Posts: 655
Re: How to use interfaces
« Reply #13 on: October 06, 2021, 12:12:00 pm »
Hello @everyone,

Would an article with a T[Contained|Aggregated]Object example (explaining how to use interfaces in such classes in order to remain in the explicit origineelle Free Object Pascal (Create..Free) memory management paradigm) be useful ( source: https://forum.lazarus.freepascal.org/index.php/topic,46181.msg328478.html#msg328478; personally, I don't like reference counting. I prefer to keep control over explicitly destroy everything that I've previously created)?
« Last Edit: October 06, 2021, 12:17:32 pm by devEric69 »
use: Linux 64 bits (Ubuntu 20.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

Thaddy

  • Hero Member
  • *****
  • Posts: 18938
  • Glad to be alive.
Re: How to use interfaces
« Reply #14 on: October 06, 2021, 12:16:57 pm »
You are right, but that takes a bit more effort. We have to review all entries related to interfaces. And there are morons advocating CORBA over COM: that is not a bad thing, but we will need to exlpain that CORBA interfaces are nor automatically released. And so forth.
wiki's are in more ways than one unreliable.
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

 

TinyPortal © 2005-2018