confusing destructor

BlitzMax Forums/BlitzMax Beginners Area/confusing destructor

kimgar(Posted 2007) [#1]
umm, i was under the impression that this should output "destructor was called"?

Type Ttest
	Method New()
		Print "constructor was called"
	End Method
	
	Method Delete()
		Print "destructor was called"
	End Method
End Type

Local a:Ttest = New Ttest
a = Null


the reason i ask is that i wanted to call the destructor from another class, so i was kind of hoping that something like this would work :

Type Ttest
	Method New()
		Print "constructor was called"
	End Method
	
	Method Delete()
		Print "destructor was called"
	End Method
End Type

Type Tkill
	Method killReference:Ttest(tmp:Ttest)
		tmp = Null
	End Method
End Type

Local a:Ttest = New Ttest
Local b:Tkill = New Tkill
b.killReference(a)


but no luck with that either, i am sorry if this has been covered before, i've been reading and reading, got a feeling it's got to do with the GC and passing references - but i just don't get it...

i am a OOP newbie, so please bear with me for asking silly questions....


Gabriel(Posted 2007) [#2]
Destructors are not guaranteed to be called, simply because the Garbage Collector ( by default ) runs when it wants to and your program may finish before the destructor is called.

Type Ttest
	Method New()
		Print "constructor was called"
	End Method
	
	Method Delete()
		Print "destructor was called"
	End Method
End Type

Local a:Ttest = New Ttest
a = Null
GCCollect


If you force collection as in above, you'll see it gets called. But you should not rely on destructors for the reason I explained above.


tonyg(Posted 2007) [#3]
Type Tkill doesn't have a destructor.
Type Ttest
	Method New()
		Print "constructor was called"
	End Method
	
	Method Delete()
		Print "destructor was called"
	End Method
End Type

'Type Tkill
'	Method killReference:Ttest(tmp:Ttest)
'		tmp = Null
'	End Method
'End Type

Local a:Ttest = New Ttest
Local b:Ttest = New Ttest
b=Null
GCCollect()

You also have to be careful that Garbage Colleciton might not have run by the time the program finishes (in which case 'delete' never gets called).
Basically :
You null an object.
The object is marked for collection
Garbage Collector comes along and runs delete()
Hope it helps.


kimgar(Posted 2007) [#4]
[edit] ops


kimgar(Posted 2007) [#5]
aaah, finally, one word and all the pieces came together : GCCollect - thanks alot Gabriel!

tonyG, yes, the tKill reference can hang around, it won't need to clear, i was kind of hoping to use tKill to trigger the tTest destructor...if that makes any sense...

can i set a = Null from another scope (class/function)?

a global reference was my last resort, but that does not work either...

global a:Ttest = New Ttest

function killFunc()
    a = Null
end function



grable(Posted 2007) [#6]
That wouldnt work, since "tmp" is within the scope of the method.

Youd have to use a Var parameter instead:
Global test:Object = "test"
killReference(test)
If Not test Print "killed"

Function killReference:Ttest(tmp:Object Var)
  tmp = Null
EndFunction




kimgar(Posted 2007) [#7]
aaaah, YES! VAR!

another word, another puzzle in place, great grable!

it works like a charm now, thanks for all the help!