Recent

Author Topic: question about copy overload for a Record being passed as value to a function  (Read 506 times)

jamie

  • Hero Member
  • *****
  • Posts: 7707
Lets say I have a record with an Operator overload "Copy" or := and I pass a record to a function by value, does the compiler used this operator when doing so and also does the compiler use the Initialize operator if one is supplied in the Record def?

 In converting C++ code, it seems there may be some semantics not fully covered in detail in documentation that I can find anywhere.
  C++ uses the operator overloads when passing to a function as value, otherwise as REF does not call these.

 while we are at it, is there any reason CLASSES can't have operator overloads? I know I can create overloads within the unit of Type declaration for Classes but that limited and only works in FpcObject mode and does not seem to offer an easy way to get the SELF parameter.

 Just checking

Jamie


The only true wisdom is knowing you know nothing

Warfley

  • Hero Member
  • *****
  • Posts: 2058
Lets say I have a record with an Operator overload "Copy" or := and I pass a record to a function by value, does the compiler used this operator when doing so and also does the compiler use the Initialize operator if one is supplied in the Record def?
Copy is used on Assignment. If you pass it as a value parameter AddRef is used. In how far initialize is used, I don't know right of the bat.

In converting C++ code, it seems there may be some semantics not fully covered in detail in documentation that I can find anywhere.
  C++ uses the operator overloads when passing to a function as value, otherwise as REF does not call these.
C++ only has the copy constructor and assignment operator. Pascal distinguishes between Copy and AddRef (PascalDragon explained that reason once, I already forgot). This makes it a bit more difficult but can be worked with.

while we are at it, is there any reason CLASSES can't have operator overloads? I know I can create overloads within the unit of Type declaration for Classes but that limited and only works in FpcObject mode and does not seem to offer an easy way to get the SELF parameter.
Well general operator overloads because they create temporary objects and this does not mix well with manual memory management. Take the + operator, if you have A+B+C you create first a temporary object B+C and then call the Operator with it and A again (at least I believe it was reverse order, due to AST parsing, maybe it's first A+B and then +C). With classes that temporary object would never be freed.
But you can use operator overloads with COM Interfaces as those are reference counted and do not run into that Problem, see the unit gmp for examples. What is not possible is to combine overloads with generics in interfaces, this is only possible with records.

If you mean management operators (initialize, finalize, copy, addref), well thats simple: You have constructors and destructors and the rest is just pointers so no actual copying happens. So they are not needed.
The better question is why they don't exist for objects ;)

jamie

  • Hero Member
  • *****
  • Posts: 7707
Yes that would be nice if OBJECTS could be advanced. I kind of like them because I can create static type class, they are simply lacking some items like operator overloads and initialize and finalize overloads for auto management.

 Plus, I can inheritance  :o

Jamie
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
Plus, I can inheritance  :o

Jamie
Objects support inheritance since TP5 days. Only the syntax differs a bit:
Code: Pascal  [Select][+][-]
  1. {$mode TP}
  2. type
  3.   PBase=^TBase;
  4.   TBase = object
  5.     FField:string;
  6.     constructor init;
  7.     destructor Done;virtual;
  8.     procedure WhoAmI;Virtual;
  9.   end;
  10.  
  11.   PDerived = ^TDerived;
  12.   TDerived = object(TBase)
  13.   public
  14.     constructor init;
  15.     procedure WhoAmI;Virtual;// NOT override with object syntax.
  16.   end;
  17.  
  18.   constructor TBase.Init;
  19.   begin
  20.     FField := 'Base';
  21.   end;
  22.  
  23.   destructor TBase.Done;
  24.   begin
  25.     writeln('Done');
  26.   end;
  27.  
  28.   constructor TDerived.Init;
  29.   begin
  30.     FField := 'Derived';
  31.   end;
  32.  
  33.    
  34.   procedure TBase.WhoAmI;
  35.   begin
  36.     writeln(FField);
  37.   end;
  38.  
  39.   procedure TDerived.WhoAmI;
  40.   begin
  41.     writeln(FField);
  42.   end;
  43. var
  44.   a:PBase;  
  45.   b:PDerived;
  46. begin
  47.   New(a,init);
  48.   New(b,init);
  49.   a^.WhoAmI;
  50.   b^.WhoAmI;
  51.   dispose(a, done);
  52.   dispose(b, done);// calls inherited done
  53. end.
See also the language reference guide:
https://www.freepascal.org/docs-html/current/ref/refch5.html#x59-790005

Since constructors/destructors are supported, initialization and finalization are also supported. That requires the use of the pointer types.
(Well, otherwise you need to call them manually)

The Freevision library has many advanced examples for inheritance and contructors /destructors. It is build on the concept.
« Last Edit: May 05, 2026, 06:55:37 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

cdbc

  • Hero Member
  • *****
  • Posts: 2787
    • http://www.cdbc.dk
Hi
Good example Thaddy =^
...brings me right back to TP5.5  :D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

jamie

  • Hero Member
  • *****
  • Posts: 7707
What did I say?

In anycase, for auto ctor and dtor look at this.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeswitch advancedrecords}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  10.  
  11. type
  12.  
  13.   { TMyCClass }
  14.  
  15.   TMyCClass = record
  16.  
  17.   type
  18.  
  19.     { ta }
  20.  
  21.     ta = class
  22.       function Test: boolean;
  23.     end;
  24.    Public
  25.    Instance:Ta;
  26.    class operator initialize(Var a: TMyCClass);
  27.    Class Operator Finalize(var a:TMyCClass);
  28.   end;
  29.  
  30.   { TForm1 }
  31.  
  32.   TForm1 = class(TForm)
  33.     Button1: TButton;
  34.     procedure Button1Click(Sender: TObject);
  35.   private
  36.  
  37.   public
  38.  
  39.   end;
  40.  
  41. var
  42.   Form1: TForm1;
  43.  
  44. implementation
  45.  
  46. {$R *.lfm}
  47.  
  48. { TMyCClass }
  49.  
  50. class operator TMyCClass.initialize(var a: TMyCClass);
  51. begin
  52.  a.instance:=Ta.Create;
  53. end;
  54.  
  55. class operator TMyCClass.Finalize(var a: TMyCClass);
  56. begin
  57.   a.instance.Free;
  58. end;
  59.  
  60. { TMyCClass.ta }
  61.  
  62. function TMyCClass.ta.Test: boolean;
  63. begin
  64.   Result := True;
  65. end;
  66.  
  67. { TForm1 }
  68.  
  69. procedure TForm1.Button1Click(Sender: TObject);
  70. Var
  71.   T:TmyCClass;
  72. begin
  73.   Caption:=T.Instance.Test.ToString;
  74. end;
  75.  
  76. end.
  77.  

Now if only we default methods like arrays, it would make this even nicer.
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
YOU wrote "inheritance". Like classes, objects do not need the operators: they have constructors.
You can rewrite your example in the manner of the lesson I gave you above.

Classes vs Objects is mainly that classes are always a pointer type and that is because they internally pretty much follow the object type with pointer dereference. It is a lexical improvement. Objects do not need implicit operators for that reason.
Just because you are unfamiliar or uncomfortable with the syntax, does not mean you are in any way limited.
To make a comparison: operating on TClass instead of Tobject.
« Last Edit: May 05, 2026, 01:37:44 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

jamie

  • Hero Member
  • *****
  • Posts: 7707
Having trouble keeping up with me ;D
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
No, fact: there is no reason to implement it, because objects have constructors and destructors.
objects are fine constructs. You can even initialize them with constructors.

jamie

  • Hero Member
  • *****
  • Posts: 7707
All i can say is if you cant actually see what i wrote for auto ctor and dtors. You must be blind in one eye and cant see out the other.

Jamie.
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
Your code was bad...? Replace it with a Pointer to object as I explained...

There is really no compelling reason.
objects are fine constructs. You can even initialize them with constructors.

jamie

  • Hero Member
  • *****
  • Posts: 7707
The proof is in the pudding and I have a whole bowl of it
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 19165
  • Glad to be alive.
What exactly do you want? (changing code examples to NOT use objects does not help, as cdbc can confirm, do not change the rules while playing...)
Apart from that it makes no sense.
I am happy to provide you with an example on how to properly embed an object inside a class and the object does NOT need class operators.
« Last Edit: May 05, 2026, 07:54:45 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

cdbc

  • Hero Member
  • *****
  • Posts: 2787
    • http://www.cdbc.dk
Hi
For a real life example, take a look at the implementation of a generic factory, I've done in the P.I.S.S. pluginmgr itself....
I did that to get a static /class/ to reference in a property (turned into just a function later) and to keep codetools working __with__ generics (they piss me off sometimes)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

 

TinyPortal © 2005-2018