[solved] problem with operator let ?

General FreeBASIC programming questions.
Post Reply
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

[solved] problem with operator let ?

Post by D.J.Peters »

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[3]=10 is in real c.m[3]=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 m
end type
destructor tVector
  if n then delete [] m
end destructor  
constructor tVector(nDims as integer)
  print"tVector(" & nDims & ")"
  n=nDims: if n then m=new single[n]
end constructor
constructor tVector(x as single,y as single)
  n=2:m=new single[n]:m[0]=x:m[1]=y
  print "tVector(" & this & ")"
end constructor
constructor tVector(x as single,y as single,z as single)
  n=3:m=new single[n]:m[0]=x:m[1]=y:m[2]=z
  print "tVector(" & this & ")"
end constructor
constructor tVector(x as single,y as single,z as single,w as single)
  n=4:m=new single[n]:m[0]=x:m[1]=y:m[2]=z:m[3]=w
  print "tVector(" & this & ")"
end constructor
operator 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]:next
end 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 res
end operator

operator -(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 res
end operator

var a = tVector(1,2)
var b = tVector(1,2,3)
var c = tVector(1,2,3,4)
var d = c 
var e = a-b
d.m[3]=10
print a,b,c,d,e
print a.n,b.n,c.n,d.n,e.n
sleep
Last edited by D.J.Peters on Feb 11, 2020 20:23, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: problem with operator let ?

Post by D.J.Peters »

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]:next
end constructor
But why is operator let not called ?

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

Re: problem with operator let ?

Post by Xusinboy Bekchanov »

But in this case Let is called

Code: Select all

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

Re: problem with operator let ?

Post by MrSwiss »

D.J.Peters wrote:But why is operator let not called ?
I can't answer that one.

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: 1923
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: problem with operator let ?

Post by Imortis »

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
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: problem with operator let ?

Post by fxm »

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: 1923
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: problem with operator let ?

Post by Imortis »

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: 8586
Joined: May 28, 2005 3:28
Contact:

Re: [solved] problem with operator let ?

Post by D.J.Peters »

thank you all

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

Re: [solved] problem with operator let ?

Post by fxm »

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: 8586
Joined: May 28, 2005 3:28
Contact:

Re: [solved] problem with operator let ?

Post by D.J.Peters »

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,z
end type
operator tVector . cast as string
  return "[" & x & ", " & y & ", " & z & "]"
end operator

type 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 type
function tVectorList . count as uinteger
  return ubound(vectors)+1
end function
function tVectorList . add() as uinteger
  var index = count : redim preserve vectors(index) : return index
end 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 index
end 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 a
dim as tVectorList a
a.add(1,2,3)                       ' by x,y,z triple
a.add(type<tVector>(4,5,6))        ' by tVector
a[2].x = 7: a[2].y = 8: a[2].z = 9 ' by operator []

dim as tVectorList b
print "list a"
for i as integer = 0 to a.count-1
  print a[i]
next:print
print "list b = list a"
b=a ' assign list a to b
print
print "list b is a deep copy of list a now !"
print "list a,b "
print a.count,b.count
for i as integer = 0 to a.count-1
  print a[i],b[i]
next:print
print "change item [0].z in list b"
b[0].z=42
print "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:print
sleep
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: [solved] problem with operator let ?

Post by fxm »

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 Type

Dim As UDT src
Redim src.array(1 To 5)
For I As Integer = Lbound(src.array) to Ubound(src.array)
  src.array(I) = I
Next I

Dim As UDT dst

Print "destination array:"
For I As Integer = Lbound(dst.array) to Ubound(dst.array)
  Print dst.array(I)
Next I
Print

dst = src

Print "destination array:"
For I As Integer = Lbound(dst.array) to Ubound(dst.array)
  Print dst.array(I)
Next I
Print

Sleep
'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: 8586
Joined: May 28, 2005 3:28
Contact:

Re: [solved] problem with operator let ?

Post by D.J.Peters »

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
Post Reply