Howto clone UDT variable from its pointer ?? (Partially solved)

General FreeBASIC programming questions.
Post Reply
ppf
Posts: 88
Joined: Oct 10, 2017 6:41

Howto clone UDT variable from its pointer ?? (Partially solved)

Post by ppf »

Hi,

while understanding pointer possibilities in coding, founding this important problem, so I am looking for an example if and how is possible to replicate - clone - rebuild one UDT variable under different name.
Thank you for suggestions .

Code: Select all

type myUdt
  as byte a
  as ushort b
  as string * 9 fs
end type

dim A as myUdt  
dim pA as myUdt Ptr=@A
A.a=26
A.b=1000
A.fs="123456789"


'needed result
var B= ??


(edit)
forgot fill values of A
Last edited by ppf on May 07, 2019 12:00, edited 1 time in total.
Xusinboy Bekchanov
Posts: 789
Joined: Jul 26, 2018 18:28

Re: Howto clone UDT variable from its pointer ??

Post by Xusinboy Bekchanov »

That's the way to do it:

Code: Select all

var B= A
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Howto clone UDT variable from its pointer ??

Post by fxm »

Code: Select all

var B = A  '' or Dim B as myUdt = A
Print B.a, B.b, B.fs
ppf
Posts: 88
Joined: Oct 10, 2017 6:41

Re: Howto clone UDT variable from its pointer ??

Post by ppf »

Yes, thanks, this is copy variant.

But reconstruction only from pointer address of udt variable ??
I remember, somewhere I saw example (maybe fxm's).
There was pointers for every field of type and some formula with Cast and maybe Offset
Bookmarked page, searching my archive...
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Howto clone UDT variable from its pointer ??

Post by fxm »

You can also define a reference to A:
Different name, but referring to the same object (no copy).

Code: Select all

Var Byref B = A  '' or Dim Byref B As myUdt = A
Print B.a, B.b, B.fs
ppf
Posts: 88
Joined: Oct 10, 2017 6:41

Re: Howto clone UDT variable from its pointer ?? (Partially solved)

Post by ppf »

After some experiments+reading forum and my archive small success

In case we know datatype of clone directly and can dimensioning it directly too,
then solution is like this:

Code: Select all

dim B as myUdt  
 B.a=pA->a
 B.b=pA->b
 B.fs=pA->fs

? "B ";B.a,B.b,B.fs
Second question: But what in case if we know only pointer particles and type of clone must be recognized in some way ?
This looks intristingly to solve and similar to my previous question (other topic),
going to further searching..
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Howto clone UDT variable from its pointer ??

Post by Tourist Trap »

fxm wrote:

Code: Select all

Var Byref B = A  '' or Dim Byref B As myUdt = A
Print B.a, B.b, B.fs
Hi all,

@fxm, it's also what I tend to name "clone", but I guess it's something inherited from VB somehow where Classes are byref stuff.

Anyway, there is something else that I want to ask, that completes the question.

In the exemple below, we see that the copy obtained by assignation copies also the pointer value.

Code: Select all

#macro _P(expression)
    ? #expression, expression
#endMacro

type UDT
    declare constructor()
    declare destructor()
        as integer  _dummyInsideValue
        as any ptr  _dummyInsideReference
end type
constructor UDT()
    THIS._dummyInsideValue = 111
    THIS._dummyInsideReference = allocate(1)
end constructor
destructor UDT()
    deallocate THIS._dummyInsideReference
end destructor

dim as UDT  uu1
_P(uu1._dummyInsideReference)

dim as UDT uu2 = uu1
_P(uu2._dummyInsideReference)

sleep

Code: Select all

uu1._dummyInsideReference   13904352
uu2._dummyInsideReference   13904352
We don't have first a new ALLOCATE (or constructor call), and then a copy of the value pointed in the new allocated pointer.
If it did, it would be a DEEP CLONING, according to this page https://www.codeproject.com/Articles/46 ... cts-in-NET.
Is there a way to ensure deep cloning in FB, based on implementing a copy constructor? Or something?
ppf wrote: Second question: But what in case if we know only pointer particles and type of clone must be recognized in some way ?
This looks intristingly to solve and similar to my previous question (other topic),
going to further searching..
Hi ppf, not sure I understand your question. But VAR B = A, or VAR BYREF B = A, work both very well. (you don't have to know the type of A then, the compiler knows it for you)
Last edited by Tourist Trap on May 07, 2019 11:57, edited 2 times in total.
ppf
Posts: 88
Joined: Oct 10, 2017 6:41

Re: Howto clone UDT variable from its pointer ??

Post by ppf »

Thanks for that suggestion ( referring to the same object), fxm, I'll try it too.

@Tourist Trap
due this
viewtopic.php?f=3&t=27580
Finding a datatype having solved with help of"Enum" 2 weeks back, in my program, but don't like it.
RandomAccesFileread routine has big 'select case' block with 'Get' command for every datatype detected.
This is unneeded, I want to have there only one 'Get' command.
Need better or a direct way to access it all via indexes, thought.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Howto clone UDT variable from its pointer ??

Post by Tourist Trap »

ppf wrote: due this
viewtopic.php?f=3&t=27580
Finding a datatype having solved with help of"Enum" 2 weeks back, in my program, but don't like it.
RandomAccesFileread routine has big 'select case' block with 'Get' command for every datatype detected.
This is unneeded, I want to have there only one 'Get' command.
Need better or a direct way to access it all via indexes, thought.
Hi ppf,

do you know the TYPEOF(variable) command?

Code: Select all

type UDT1
    as integer _dummy
end type

dim as UDT1  uu

#print typeOf(uu)
#if typeOf(uu)=typeOf(UDT1) 
    ? "ok"
#endIf
#if typeOf(uu)=typeOf(integer)
    ? "weird"
#endIf
Can it help?

In any case something like that works:

Code: Select all

type UDT1
    as integer _dummy
end type

dim as UDT1 uu

Dim buffer As TYPEOF(uu)

var f = freefile()
Open "test.bas" For Binary Access Read As #f
Get #f, , buffer
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Howto clone UDT variable from its pointer ??

Post by fxm »

Tourist Trap wrote: In the exemple below, we see that the copy obtained by assignation copies also the pointer value.

Code: Select all

#macro _P(expression)
    ? #expression, expression
#endMacro

type UDT
    declare constructor()
    declare destructor()
        as integer  _dummyInsideValue
        as any ptr  _dummyInsideReference
end type
constructor UDT()
    THIS._dummyInsideValue = 111
    THIS._dummyInsideReference = allocate(1)
end constructor
destructor UDT()
    deallocate THIS._dummyInsideReference
end destructor

dim as UDT  uu1
_P(uu1._dummyInsideReference)

dim as UDT uu2 = uu1
_P(uu2._dummyInsideReference)

sleep

Code: Select all

uu1._dummyInsideReference   13904352
uu2._dummyInsideReference   13904352
We don't have first a new ALLOCATE (or constructor call), and then a copy of the value pointed in the new allocated pointer.
If it did, it would be a DEEP CLONING, according to this page https://www.codeproject.com/Articles/46 ... cts-in-NET.
Is there a way to ensure deep cloning in FB, based on implementing a copy constructor? Or something?
Your previous example may even crash because the allocated memory is deallocated 2 times (when uu1 and uu2 are deleted).

One solution is indeed to implement a copy constructor:

Code: Select all

#macro _P(expression)
    ? #expression, expression
#endMacro

type UDT
    declare constructor()
    declare constructor(byref u as UDT)
    declare destructor()
        as integer  _dummyInsideValue
        as any ptr  _dummyInsideReference
end type
constructor UDT()
    THIS._dummyInsideReference = allocate(1)
end constructor
constructor UDT(byref u as UDT)
    constructor()
    THIS._dummyInsideValue = u._dummyInsideValue
end constructor
destructor UDT()
    deallocate THIS._dummyInsideReference
end destructor

dim as UDT  uu1
uu1._dummyInsideValue = 111
_P(uu1._dummyInsideReference)
? uu1._dummyInsideValue

dim as UDT uu2 = uu1
_P(uu2._dummyInsideReference)
? uu2._dummyInsideValue

sleep
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Howto clone UDT variable from its pointer ??

Post by fxm »

ppf wrote: RandomAccesFileread routine has big 'select case' block with 'Get' command for every datatype detected.
This is unneeded, I want to have there only one 'Get' command.
Need better or a direct way to access it all via indexes, thought.
With FreeBASIC, you can not dynamically change the type of a variable. So you need to have as much Get line as variable type.
ppf
Posts: 88
Joined: Oct 10, 2017 6:41

Re: Howto clone UDT variable from its pointer ?? (Partially solved)

Post by ppf »

fxm wrote
With FreeBASIC, you can not dynamically change the type of a variable. So you need to have as much Get line as variable type.
That's a pity, hmm, I'll try some workaround with "#macro" concatenation of strings to get commands.
Maybe, if would be possible to define type as indexed datatype ???
I cannot remember to such feature, must read manual again.Pointers leads me to do crazy things, however.

Code: Select all

type myUdt(1)
	'blabla
end type

type myUdt(2)
	'blabla
end type
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Howto clone UDT variable from its pointer ?? (Partially solved)

Post by fxm »

ppf wrote:Maybe, if would be possible to define type as indexed datatype ???
No.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Howto clone UDT variable from its pointer ??

Post by fxm »

fxm wrote:With FreeBASIC, you can not dynamically change the type of a variable. So you need to have as much Get line as variable type.
For example, to display the different data fields of different objects, but all derived from a common 'Object' base-type (a unique procedure, but containing the code for each UDT):

Code: Select all

Type UDT1 Extends Object
  Dim I As Byte = 123
  Dim X As Integer = 456789
  ' user fields
End Type

Type UDT2 Extends Object
  Dim D As Single = 3.14
  Dim X As Double = 3.14159
  ' user fields
End Type

Type UDT3 Extends Object
  Dim S As String = "abc"
  Dim X As Zstring * 6+1= "defghi"
  ' user fields
End Type

Sub UDTdisplay (Byval p As Object Ptr)
  If *p Is UDT1 Then Print Cptr(UDT1 Ptr, p)->I, Cptr(UDT1 Ptr, p)->X
  If *p Is UDT2 Then Print Cptr(UDT2 Ptr, p)->D, Cptr(UDT2 Ptr, p)->X
  If *p Is UDT3 Then Print Cptr(UDT3 Ptr, p)->S, Cptr(UDT3 Ptr, p)->X
End Sub

Dim u1 As UDT1, u2 As UDT2, u3 As UDT3
Dim As Object Ptr pUDT(1 To 3) = {@u3, @u1, @u2}

For I As Integer = 1 To 3
  UDTdisplay(pUDT(I))
Next I

Sleep
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Howto clone UDT variable from its pointer ?? (Partially solved)

Post by fxm »

Variant of above code, but using polymorphism instead of the 'Is' Operator:

Code: Select all

Type UDT Extends Object
  Declare Abstract Sub UDTdisplay ()
End Type

Type UDT1 Extends UDT
  Dim I As Byte = 123
  Dim X As Integer = 456789
  Declare Virtual Sub UDTdisplay ()
  ' user fields
End Type
Sub UDT1.UDTdisplay ()
  Print This.I, This.X
End Sub

Type UDT2 Extends UDT
  Dim D As Single = 3.14
  Dim X As Double = 3.14159
  Declare Virtual Sub UDTdisplay ()
  ' user fields
End Type
Sub UDT2.UDTdisplay ()
  Print This.D, This.X
End Sub

Type UDT3 Extends UDT
  Dim S As String = "abc"
  Dim X As Zstring * 6+1= "defghi"
  Declare Virtual Sub UDTdisplay ()
  ' user fields
End Type
Sub UDT3.UDTdisplay ()
  Print This.S, This.X
End Sub

Dim u1 As UDT1, u2 As UDT2, u3 As UDT3
Dim As UDT Ptr pUDT(1 To 3) = {@u3, @u1, @u2}

For I As Integer = 1 To 3
  pUDT(I)->UDTdisplay()
Next I

Sleep
This solution is better than the previous because one can add new derived-types without changing the existing code.
Post Reply