## [solved] problem with operator let ?

General FreeBASIC programming questions.
D.J.Peters
Posts: 7942
Joined: May 28, 2005 3:28

### [solved] problem with operator let ?

To make a deep copy I implemented the "operator let" but
var d = c
does not call the let operator why is it or what i'm doing wrong ?

In this case d is a reference to c (not a new copy) and d.m=10 is in real c.m=10

thank you

Joshy

Code: Select all

`#define _min(x,y) iif((x)<(y),(x),(y))type tVector  declare destructor  declare constructor (nDims as integer=0)  declare constructor (x as single,y as single)  declare constructor (x as single,y as single,z as single)  declare constructor (x as single,y as single,z as single,w as single)  declare operator let (byref r as tVector)  declare operator cast as string  as integer    n  as single ptr mend typedestructor tVector  if n then delete [] mend destructor  constructor tVector(nDims as integer)  print"tVector(" & nDims & ")"  n=nDims: if n then m=new single[n]end constructorconstructor tVector(x as single,y as single)  n=2:m=new single[n]:m=x:m=y  print "tVector(" & this & ")"end constructorconstructor tVector(x as single,y as single,z as single)  n=3:m=new single[n]:m=x:m=y:m=z  print "tVector(" & this & ")"end constructorconstructor tVector(x as single,y as single,z as single,w as single)  n=4:m=new single[n]:m=x:m=y:m=z:m=w  print "tVector(" & this & ")"end constructoroperator tVector .let (byref r as tVector)  print "let"  n=r.n : if n then m=new single[n] : for i as integer=0 to n-1 : m[i]=r.m[i]:nextend operator  operator tVector . cast as string  var sResult="["  for i as integer = 0 to n-1    sResult &= m[i]:if i<n-1 then sResult &= ","  next  return sResult & "]"end operator operator -(l as tVector) as tVector  var res=tVector(l.n)  for i as integer = 0 to l.n-1 : res.m[i]=-l.m[i] : next    return resend operatoroperator -(l as tVector,r as tVector) as tVector  var n=_min(l.n,r.n)  var res=tVector(n)  for i as integer = 0 to n-1    res.m[i]=l.m[i]-r.m[i]  next    return resend operatorvar a = tVector(1,2)var b = tVector(1,2,3)var c = tVector(1,2,3,4)var d = c var e = a-bd.m=10print a,b,c,d,eprint a.n,b.n,c.n,d.n,e.nsleep`
Last edited by D.J.Peters on Feb 11, 2020 20:23, edited 1 time in total.
D.J.Peters
Posts: 7942
Joined: May 28, 2005 3:28

### Re: problem with operator let ?

I know I can use a "deep copy" constructor like:

Code: Select all

`declare constructor (r as tVector)...constructor tVector(r as tVector)  print"tVector(" & r & ")"  n=r.n : if n then m=new single[n] : for i as integer=0 to n-1 : m[i]=r.m[i]:nextend constructor`
But why is operator let not called ?

Joshy
Xusinboy Bekchanov
Posts: 115
Joined: Jul 26, 2018 18:28

### Re: problem with operator let ?

But in this case Let is called

Code: Select all

`d = c`
MrSwiss
Posts: 3348
Joined: Jun 02, 2013 9:27
Location: Switzerland

### Re: problem with operator let ?

D.J.Peters wrote:But why is operator let not called ?

But I remember, that a overloaded constructor, was the only solution,
when dealing with pointers (using New/Delete, with a UDT).

Assuming:
reference = dereferenced pointer
Imortis
Moderator
Posts: 1667
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

### Re: problem with operator let ?

Quick glance over the FBC source: It looks like DIM and VAR are very different. What happens if you use DIM instead of VAR?
fxm
Posts: 9469
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

### Re: problem with operator let ?

Imortis wrote:Quick glance over the FBC source: It looks like DIM and VAR are very different. What happens if you use DIM instead of VAR?
This should be similar.

'var d = c' or 'dim as tVector d = c' is a short cut for the explicit syntax 'var d = tVector(c)' or 'dim as tVector d = tVector(c)'.

More generally:
- 'dim as tVector d' is a short cut for 'dim as tVector d = tVector()' when a default constructor exists (a default constructors always exisis, at least an implicit version)
- 'dim as tVector d = c' is a short cut for 'dim as tVector d = tVector(c)' when a compatible constructor with one parameter exists (a copy constructor always exists, at least an implicit version)
- for any constructor > one parameter, the constructor must always be called explicitly.

Only 'd = c' calls the let operator.
Imortis
Moderator
Posts: 1667
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

### Re: problem with operator let ?

fxm wrote:
Imortis wrote:Quick glance over the FBC source: It looks like DIM and VAR are very different. What happens if you use DIM instead of VAR?
This should be similar.

'var d = c' or 'dim as tVector d = c' is a short cut for the explicit syntax 'var d = tVector(c)' or 'dim as tVector d = tVector(c)'.

More generally:
- 'dim as tVector d' is a short cut for 'dim as tVector d = tVector()' when a default constructor exists (a default constructors always exisis, at least an implicit version)
- 'dim as tVector d = c' is a short cut for 'dim as tVector d = tVector(c)' when a compatible constructor with one parameter exists (a copy constructor always exists, at least an implicit version)
- for any constructor > one parameter, the constructor must always be called explicitly.

Only 'd = c' calls the let operator.

As I said it was a quick glance. I could not take the time just then to do a full read over the code. Thanks for the correction.
D.J.Peters
Posts: 7942
Joined: May 28, 2005 3:28

### Re: [solved] problem with operator let ?

thank you all

Joshy
fxm
Posts: 9469
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

### Re: [solved] problem with operator let ?

To go further on the subject, there is a case where the copy-assignment operator can replace the implicit copy-constructor operator.

Looking at my Constructors, '=' Assignment-Operators, and Destructors (advanced, part #2) article:
(see the condition combination in red)
Compiler interaction (with default-constructor, copy-constructor, and copy-assignment operator)
During assignments or copy-constructions, the compiler interacts with the different calls of copy-assignment operators, default-constructors and copy-constructors, in order to optimize the copy for resulting objects, making the best use of the member procedures provided by the user (maybe non-exhaustively).

• For an assignment ('object2 = object1')
Algorithm:
If (Type has a copy-assignment operator) Then
| => the copy-assignment opertator of Type is called
Else
| If (Type has a Base with default-constructor) AND (Type has a Base with copy-assignment operator) Then
| | => the copy-assignment operator of Base is called (for Base fields)
| | => a shallow-copy is done on only Type fields
| Else
| | => a full shallow-copy is done on all fields
| End If
End If

• For a copy-construction ('Dim As typename object2 = object1')
Algorithm:
If (Type has a Base with default-constructor) Then
| => the default-constructor of Base is called
End If
If (Type has a copy-constructor) Then
| => the copy-constructor of Type is called
Else Then
| => the Type object is implicitly default-constructed (even if exists an explicit Type default-constructor)
| If (Type has a copy-assignment operator) Then
| | If (Type has an object field with a default-constructor) OR (Type has a Base with default-constructor) Then
| | | => the copy-assignment operator of Type is called
| | Else
| | | => a full shallow-copy is done on all fields
| | End If
| Else
| | If (Type has a Base with default-constructor) AND (Type has a Base with copy-assignment operator) Then
| | | => the copy-assignment operator of Base is called (for Base fields)
| | | => a shallow-copy is done on only Type fields
| | Else
| | | => a full shallow-copy is done on all fields
| | End If
| End If
End If
The easiest way to impose this condition combination in your code is to just declare your Type as 'tVector Extends Object'.

Try this very simple adding to your code and see the result!
D.J.Peters
Posts: 7942
Joined: May 28, 2005 3:28

### Re: [solved] problem with operator let ?

This code is the opposite situation !
No deep copy constructor no let operator but list B is a "deep copy" of list A !

I wonder me how it works ?

joshy

Code: Select all

`type tVector  declare operator cast as string  as single x,y,zend typeoperator tVector . cast as string  return "[" & x & ", " & y & ", " & z & "]"end operatortype tVectorList  declare function count() as uinteger  declare function add() as uinteger  declare function add(v as tVector) as uinteger  declare function add(x as single,y as single,z as single) as uinteger  declare operator [](index as uinteger) byref as tVector   as tVector vectors(any)end typefunction tVectorList . count as uinteger  return ubound(vectors)+1end functionfunction tVectorList . add() as uinteger  var index = count : redim preserve vectors(index) : return indexend function  function tVectorList . add(x as single,y as single,z as single) as uinteger  return add(type<tVector>(x,y,z))end function  function tVectorList . add(v as tVector) as uinteger  var index = count : redim preserve vectors(index)  vectors(index)=v : return indexend function  operator tVectorList . [](index as uinteger) byref as tVector  if index>=count() then redim preserve vectors(index)  return vectors(index)end operator' add 3 items to list adim as tVectorList aa.add(1,2,3)                       ' by x,y,z triplea.add(type<tVector>(4,5,6))        ' by tVectora.x = 7: a.y = 8: a.z = 9 ' by operator []dim as tVectorList bprint "list a"for i as integer = 0 to a.count-1  print a[i]next:printprint "list b = list a"b=a ' assign list a to bprintprint "list b is a deep copy of list a now !"print "list a,b "print a.count,b.countfor i as integer = 0 to a.count-1  print a[i],b[i]next:printprint "change item .z in list b"b.z=42print "be sure list b items are not a reference of list a !"for i as integer = 0 to a.count-1  print a[i],b[i]next:printsleep`
fxm
Posts: 9469
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

### Re: [solved] problem with operator let ?

Member arrays are fully taken into account by the implicit copy constructor and the implicit let operator, for all that concerns resizing and copying of all elements from the source array to the destination array.

Arrays are therefore considered as objects, but only when they are members of a UDT and only handled through their UDT instances encapsulating them:

Code: Select all

`Type UDT  Dim As Integer array(Any)End TypeDim As UDT srcRedim src.array(1 To 5)For I As Integer = Lbound(src.array) to Ubound(src.array)  src.array(I) = INext IDim As UDT dstPrint "destination array:"For I As Integer = Lbound(dst.array) to Ubound(dst.array)  Print dst.array(I)Next IPrintdst = srcPrint "destination array:"For I As Integer = Lbound(dst.array) to Ubound(dst.array)  Print dst.array(I)Next IPrintSleep`
'dst = src' is allowed and works fully
'dst.array = src.array' is disallowed

I hope that for arrays, we can one day code: 'array2 = array1'
D.J.Peters
Posts: 7942
Joined: May 28, 2005 3:28

### Re: [solved] problem with operator let ?

fxm wrote:Arrays are therefore considered as objects, but only when they are members of a UDT
Interesting, I didn't know that yet.

Thank you.

Joshy