OOP question

BlitzMax Forums/BlitzMax Beginners Area/OOP question

Jeroen(Posted 2004) [#1]
Hmmm simple questions, I feel a bit stoopid :-)
Some of the concepts I already worked with in the past, but they really need to get back in place!
Secondly, I ask this because I expect this to be a FAQ :)

1. What are the differences between methods and functions?
2. When do I use pass functions by reference? Is there an example of this?
3. And the one I keep forgetting: why should I use pointers?

Thanks! Ghehe


skidracer(Posted 2004) [#2]
1. See the explanation in the Language Reference Guide (User Defined Types section)

2. See the Blitz Runtime section of the Module Reference under Var (Apple-F1 twice on the var keyword to jump from the code editor)

3. You shouldn't, but again there is some information in the manual under Varptr.


AaronK(Posted 2004) [#3]
1. The practical difference is that Functions have no 'Self' which means they don't operate on an object. Methods on the other hand implicitly assume there is a 'Self' and so non Local/Global variables are assumed to be referencing a field of the Type.

2. Not sure - See skidracer's reply :)

3. Yeah you don't need to with BlitzMax, references are the way most things are handled and references are again implicit.


BlitzSupport(Posted 2004) [#4]
Methods can only be called from objects that have been created already (eg. r:Rocket = New Rocket).

Functions in types are handy when you're not accessing a specific object (you may not have one yet), or want to create an object. You could use an external function as in previous Blitzes to create and return an object, but that defeats the point of going object-oriented -- you want to wrap it all up into an easily copy-able type:

' This won't work!

Type Rocket

    Method Create:Rocket ()
        r:Rocket = New Rocket
        Return r
    End Method

End Type

' You can't do this, because methods can only be called from existing
' objects. Because the object doesn't exist yet, there's no Create method to call:

r:Rocket = Rocket.Create ()


Instead, you use a function embedded in the type definition, and you call it by using the type name, a period, and the function name, as in MyType.MyFunction ()...

Type Rocket

    Function Create:Rocket ()
        r:Rocket = New Rocket
        Return r
    End Function

End Type

' That's better!

r:Rocket = Rocket.Create ()


They're also handy for updating all objects at once, again via a function wrapped up in the type, because a method only works on the calling object (in this case, it would be r:Rocket calling the method and so only r:Rocket would be operated on). Here's an example function for updating all objects in a given list (assume that all 'Oink' objects are added to 'OinkList' when created)...

Global OinkList:TList = CreateList ()

Type Oink

    Field x

    Function UpdateAll ()
        For o:Oink = EachIn OinkList ' Global list...
            Print o.x
        Next
    End Function

    ' Note that methods can access type fields directly (eg. x),
    ' whereas functions need to be told which object to access them from (in the above example, o.x)...

End Type


The above would work via a method too, but you'd have to call it from a specific object, and you may not always have an object to call it from (eg. you may have a list of particles where there may not always be a particle on screen to call the UpdateAll method from). You can always call such a function by going:

Oink.UpdateAll



Jeremy Alessi(Posted 2004) [#5]
Use pass by reference when you actually want a function to change a variable that isn't global. So you can pass by reference to a function a variable that isn't global this is very useful and 'safer' than using many globals.


BlitzSupport(Posted 2004) [#6]
There's an example of that in samples/hitoro/ by the way...


AaronK(Posted 2004) [#7]
In case you need a reference - If you are used to other languages like C++ then Methods in Types are like static functions.


soja(Posted 2004) [#8]
If you are used to other languages like C++ then Methods in Types are like static functions

er... Do you mean that functions in types are like static methods in c++?


AaronK(Posted 2004) [#9]
OK, I was absolutely asleep there. Yes, you're correct.


Jeroen(Posted 2004) [#10]
Thank you all!
I bought BMax to suppport (and encourage) Blitz at this stage but I don't have a Mac, but I did see some code examples using Pear PC.

James, the differences are now clear to me!
I will always try to put functions in types, with at least the reason that I will group it the right way! Until now, functions sometimes became so "lost" in the code, with only the script filename as guideline.


Sweenie(Posted 2004) [#11]
Would this work...

Type Vec3

	Field x:float,y:float,z:float

	Method Set(x:float,y:float,z:float)
	 self.x=x
	 self.y=y
	 self.z=z	 
	End Method

	Function Create:Vec3(x:float,y:float,z:float)
	 v:Vec3 = New Vec3
	 v.x=x
	 v.y=y
	 v.z=z
	 Return v
	End Function


End Type


'One way
local Pos:Vec3 = New Vec3
Pos.x=10.0
Pos.y=20.0
Pos.z=30.0

'another way
local Pos:Vec3 = New Vec3
Pos.Set(10.0,20.0,30.0)

' yet another way...
local Pos:Vec3 = Vec3.Create(10.0,20.0,30.0)


or would I get problems because I use parameters with the same name as the fields in the type?


FlameDuck(Posted 2004) [#12]
Would this work...
Yes.
or would I get problems because I use parameters with the same name as the fields in the type?
Depends. The compiler will get it, because the variables are in a different scope. (v.x and self.x are in object scope, while x is in method scope). So the compiler won't have any problems with it.

A better question to ask is, whether it makes for very readable code.

Being a proponent of refactoring, I'd suggest using litterally different variable names, even if they are in seperate scope, in order to ease readability.