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

type tVectorList
declare function count() 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
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[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
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 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: 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