RPGCode — Object Oriented Coding — Returning References
Arrays in RPGCode have very limited functionality. They do not have set upper bounds and there are no functions to manipulate arrays. While coding an array class exceeds the scope of this document, returning references does not.
When you overload operator[] you can only take one parameter - the index in the array. People from structured programming backgrounds will find it impossible, therefore, to allow the creator to set items in the array. This, however, is not correct. When you return a reference, you make calling a function a synonym for the variable you return. Consider the following example:
method someString() { returnMethod(&g_str$) } someString() = "Hello, world!" show(someString()) wait()
The syntax for using returnMethod in this fashion is as seen above:
method returnMethod(&theVar)
Where theVar is a variable - not a value - that calling the function will become a synonym for.
Using this knowledge we can create a simple array class, like so:
// An array class CArray { // Public visibility public: // Constructor method CArray(upperBound!) // Subscript operator method operator[](idx!) // Get the upper bound method getBound() { returnMethod(m_bound!) } // Deconstructor method ~CArray() // Private visibility private: m_data[] // Main data m_bound! // Upper bound of the array } // CArray - constructor method CArray::CArray(upperBound!) { if (m_bound! >= 0) { // Bound is okay m_bound! = upperBound! } else { // Bound is no good debugger("Invalid upper bound: " + CastLit(upperBound!)) } } // CArray - subscript operator method CArray::operator[](idx!) { // Check bounds if (idx! <= m_bound! && idx! >= 0) { // Within bounds returnMethod(&m_data[idx!]) } else { // Out of bounds debugger("Out of array bounds: " + CastLit(idx!)) g_null! = 0 returnMethod(&g_null!) } } // CArray - deconstructor method CArray::~CArray() { On Error Resume Next local(i!) for (i! = 0; i! <= m_bound!; i!++) { this[i!]->release() kill(this[idx!]!) } }
You may notice the use of this. Said, this, is just the current object, and, as you'd expect, this! is a unique number representing the object.
It's also worth nothing that the array index does not need to be numerical - it can be literal, or even an object.
The CArray class also shows an example of composition, that is, having objects as members of classes. This example which makes an array of dates, illustrates this:
// Create a new array array = CArray(1) // Fill it with two CDates array[0] = CDate(2, 12, 1234) array[1] = CDate(1, 1, 1999) // Iterate over the array ub! = array->getBound() for (i! = 0; i! <= ub!; i!++) { // Show this date text(1, 1 + i!, array[i!]) } // Wait for a key wait() // Clean up array->release() kill(i!, ub!, array!)
If you'll check back at CArray's deconstructor, you'll see that it releases its members automatically so we don't need to release the two dates.
Note: This class has a problem that would be experienced when attempting to copy the object through an assignment or when passed as a parameter; we will explore this problem in Copy Constructors.
As you can see, returning references is a very powerful tool.