Strings, arrays and instances of user defined types are all different kinds of objects.
Objects are handled by reference. This means that the actual memory used by an object to store its data is shared between all the variables that refer to that object.
This makes objects very efficient to deal with, as assigning an object to a variable simply involves assigning a reference to the object - not an entire object. Passing objects to functions and returning objects from functions is also very efficient as again only references need to be copied.
BlitzMax uses a technique known as reference counting to keep track of objects that are in use by your program.
The basic idea behind reference counting is that each object includes a counter reflecting the number of variables referencing that object. When an object's counter reaches 0, the object is no longer in use and its memory can be returned to the system.
The process of returning unused objects to the system is called 'garbage collection' and, by default, is performed automatically. However, it may be desirable to 'force' a garbage collection (for example, to check for memory leaks) and this can be done using the GCCollect command.
Objects can also have methods - function-like operations associated with the object. All objects, including strings and arrays, provide at least the following methods:
|ToString:String()||Convert object to a string representation.|
|Compare:Int( withObject:Object )||Returns a value less than 0 if an object is less than another object, a value greater than 0 if an object is greater than another object or the value 0 if an object equals another object.|
|SendMessage:Object( message:Object,context:Object )||Used to send a generic message to an object.|
The default implementation of the ToString method converts the address of the object to hexadecimal and returns this value as a string. String objects override this behaviour to the return the object itself.
The default implementation of the Compare method subtracts object addresses. String objects override this behaviour to return the result of a character-by-character comparison.
The SendMessage method provides a simple, generic messaging system available to all objects. The default implementation of SendMessage simply returns null.
Note that the built-in equals and not equals operators do not actually use the compare method (with one exception). Instead, these operators compare memory addresses, allowing you to determine if 2 object references actually refer to the same object. The exception to this rule is when comparisons are performed on strings, in which case a character-by-character comparison is performed instead.
It is possible to override the Compare method to something more suitable for a user-defined type. The Compare method is automatically used by the Sort method of lists, for example. When overriding the Compare method, the following precaution should be made - if the second object with which you are to compare is not a type of object this method recognises, it should return the Super (parent type's) compare method instead of 0 or another dummy value. Here is an example, for a "TScore" type:
Type TScore Field value:Int Method Compare:Int(other:Object) Local o2:TScore = TScore(other) 'if other is not a TScore, call the super compare method as fail-safe If o2 = Null Then Return Super.Compare(other) If o2.value > value Then Return -1 If o2.value < value Then Return 1 Return 0 End Method End Type
To access an object's methods, use the member access operator. For example:
Print "Hello".Compare( "Goodbye" )