Jump to content
emileverh

Need inline InterfacedObjects to be freed?

Recommended Posts

type
  ICar = interface
    ['{F476D9B5-EE8C-458D-96CD-107C80855066}']
    function GetPlateNoDashes: string;
  end;

 

type
  TCar = class(TInterfacedObject, ICar)
    function GetPlatesNoDashes: string;

   ......
  end;

 

========

 

procedure TfrmMain.DoSomething;

begin

  var car:= TCar.Create;
  ShowMessage(car.GetPlateNoDashes);

end;

 

Hi all!

 

Better late then never... I am experimenting with interfaces.....

Question: Is the variable 'car' of type ICar or TCar?  And more important, do I need to call .Free in the DoSomething procedure?

 

Regards,

Emile

 

Thanks

Edited by emileverh

Share this post


Link to post

The inline variable in question will be of type TCar as its type will be inferred from type used in constructor: TCar.

 

In such code where object instances are reference counted, you will need to explicitly specify correct type: ICar because reference counted instances need to be stored in interface references for proper initialization of reference counting mechanism.

 

var car: ICar := TCar.Create; 

 

Edited by Dalija Prasnikar
  • Like 5

Share this post


Link to post

Thanks for the quick response, and helpful answer!!  Reading lot of E-Books now....

Share this post


Link to post
5 hours ago, Dalija Prasnikar said:

In such code where object instances are reference counted, you will need to explicitly specify correct type: ICar because reference counted instances need to be stored in interface references for proper initialization of reference counting mechanism.

 

var car: ICar := TCar.Create;

Note that such usage is demonstrated in Embarcadero's documentation, though it is not explicitly called out as being a requirement:

 

https://docwiki.embarcadero.com/RADStudio/en/Inline_Variable_Declaration

procedure Test99;
begin

  // some code

  if (something) then
  begin
    var Intf: IInterface = GetInterface; // Intf.AddRef  // <-- HERE!
    var MRec: TManagedRecord = GetMRecValue; // MRec.Create + MRec.Assign
    UseIntf(Intf);
    UseMRec(MRec);
  end; // Intf.Release and MRec.Destroy are implicitly called at end of scope
  
  // more code

end; // no additional cleanup

 

  • Like 2

Share this post


Link to post

A compiler hint would be nice if you forget to explicit mention the type in this case.

Until now most of my code did not add the type by using inline vars ( strings, integers, etc. ). I you forget to mention the type with interfaced objects then you have a memory leak

Share this post


Link to post
1 hour ago, emileverh said:

A compiler hint would be nice if you forget to explicit mention the type in this case.

Until now most of my code did not add the type by using inline vars ( strings, integers, etc. ). I you forget to mention the type with interfaced objects then you have a memory leak

Compiler cannot give you appropriate hint at that place. The problem is that it doesn't know whether you need to use interface reference or not because some classes that have interfaces have reference counting disabled and are used through object references.

If compiler would give a hint that would result in many false positives and at the end such hints would be useless. This is similar situation as the one where developer declares regular variable, but uses wrong type. There are no hints for such scenarios either.

Share this post


Link to post

Thanks all.

 

I noticed a disadvantage of using interfaces... the getters and setters are exposed. I would be more cleaner to see the property only. But that's how interfaces work, no public/private area. I don't know if interfaces ( in my case ) bring me a lot ,except reference counting and cleanup stuff in a proper way.

Share this post


Link to post
On 1/6/2023 at 1:46 PM, emileverh said:

I don't know if interfaces ( in my case ) bring me a lot ,except reference counting and cleanup stuff in a proper way.

Yes, they have disadvantages. Probably base class will fit your needs more

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×