I thought I knew OOP, oops.

BlitzMax Forums/BlitzMax Programming/I thought I knew OOP, oops.

Dubious Drewski(Posted 2005) [#1]
I have run into a limitation in my knowledge of OOP.
If I write Object1 = Object2, why doesn't Object1 get it's
own block of memory to play with? Instead, they both
share the same memory as you can see if you run this
code below:

here!

Strict
Type testType
	Field a:Int
	Method update()
		a:+1
	EndMethod
EndType

Local test1: testType = New testType
Local test2: testtype = test1

For Local b = 1 To 5
	test1.update
	test2.update
Next

Print test1.a
Print test2.a


How do I copy an object along with all of it's field
values so that it is a separate entity from it's parent?


bradford6(Posted 2005) [#2]
test1 is an instance on testtype

test2 is just a pointer to test1.

in order to do a 'deep' copy you will simply create a new instance and copyt the attributes from test1 to test 2


Strict
Type testType
	Field a:Int	=0
	
	Method update()
		a:+1
	EndMethod
EndType

Local Original: testType = New testType
Local myCopy: testType = New testType

For Local b = 1 To 5
	Original.update
Next
myCopy.a = original.a

Print Original.a
Print myCopy.a



Dubious Drewski(Posted 2005) [#3]
Grr. I was hoping to avoid manual field copying. Is there no better way?

Thank you bradford for helping though.


gman(Posted 2005) [#4]

Is there no better way?


not that i have come across anyway. there were some things discussed a long time ago dealing with allocating a new block of memory and copying the memory around but i dont think it really worked well. plus, as objects get more complex and have fields that are in effect, more type instance pointers, even with copying memory those would still point to the same references. i think a pretty accepted way of handling something like this is having a clone method that returns a copy of the object instance. that way you have control over what is the same and what is different (ie whether you want any fields that are also objects to either be cloned or point to the same instance). also, something that can be implemented are create functions, one of which would create from an instance of the same type. a testType showing some of this would be
Type testType
	Field a:Int=0

	Function create:testType()
		Return New testType
	EndFunction

	Function createFromInstance:testType(other:testType)
		Return other.Clone()		
	EndFunction

	Method update()
		a:+1
	EndMethod

	Method Clone:testType()
		Local retval:testType=create()
		retval.a=a
		Return retval
	EndMethod
EndType

with options being
Local Original:testType=testType.create()
Local myCopy1:testType=Original.Clone()
Local myCopy2:testType=testType.createFromInstance(Original)



Jay Kyburz(Posted 2005) [#5]
check this out


Strict
Type testType
	Field a:Int
	Method update()
		a:+1
	EndMethod
EndType

Local test1: testType = New testType
Local test2: testtype = New test1

For Local b = 1 To 5
	test1.update
	test2.update
Next

Print test1.a
Print test2.a





N(Posted 2005) [#6]
Great, another undocumented 'feature'...


klepto2(Posted 2005) [#7]
Sorry Jay, but this is not working as it should. Your method only copies the type with its fields but not the value.

eg: test2:Testtype = New test1 is the same as
test2:TestType = New TestType

Code to prove it:

Strict
Type testType
	Field a:Int
	Method update()
		a:+1
	EndMethod
EndType

Local test1: testType = New testType

For Local b = 1 To 5
	test1.update
Next

Local test2: testtype = New test1


For Local b = 1 To 5
	test1.update
	 test2.update
Next


Print test1.a
Print test2.a


normally the test2.a should be 10 at the end but it is 5.


Grey Alien(Posted 2005) [#8]
I guessed that would be the case


Ferminho(Posted 2005) [#9]
I think Gman's copy constructor solution is the best approach - that's what I usually do in bmax and C++


Jay Kyburz(Posted 2005) [#10]
ohwell.


Hotcakes(Posted 2005) [#11]
Petition for your request here!


N(Posted 2005) [#12]
Old-ish thread, but anywho, your best option is to do something like this:

Type ICloneable
     '' Virtual method
     Method Clone:ICloneable( )
          Throw "Object cannot be cloned"
     End Method
End Type

Type WeebleBobble Extends ICloneable
     Field A:Int
     Field B:Foobar '' also implements ICloneable

     Method Clone:ICloneable( into:ICloneable )
          Local i:WeebleBobble = WeebleBobble( into )
          If ( i = Null )
               i = new WeebleBobble
          EndIf
          i.A = A
          i.B = B.Clone( )
'' Now, if this class wasn't directly below ICloneable you would do this
''          Super.Clone( i )
          Return i
     End Method
End Type