OOP question
BlitzMax Forums/BlitzMax Beginners Area/OOP question
| ||
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 |
| ||
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. |
| ||
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. |
| ||
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 |
| ||
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. |
| ||
There's an example of that in samples/hitoro/ by the way... |
| ||
In case you need a reference - If you are used to other languages like C++ then Methods in Types are like static functions. |
| ||
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++? |
| ||
OK, I was absolutely asleep there. Yes, you're correct. |
| ||
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. |
| ||
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? |
| ||
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. |