More Than an Ordinary Reference

If you know Java or Eiffel, you know what an object reference means. It is an pointer to a piece of object storage; so that the state of the object can be accessed through the pointer. Object storage are allocated and deleted dynamically. Both Java and Eiffel provide garbage collection to prevent memory leak. Programmers feel free to ask more and more object storage and never worry about releasing it. Dangling objects are deleted and the freed storage is collected automatically by the system.

Sounds a good idea, but not good enough.

The first problem is that the smart object reference supported by the language is very limited. It works only on the declared reference variables. Object references can be something else, for example, a handle to a system resource (either hardware or software) or a name to an object in a persistent object storage. If the language does not support smart references to these objects, programmers still have to worry about cleaning things up. An oversight may exhaust the system resource. You might already have the experience in Windows programming.

The second problem is that the "stupid" object reference is still required, for either the efficiency reason, or low-level system programming nature. Stupid object references may be static. They are not necessarily as dangerous as C/C++ pointers. They can be pointers to be statically allocated objects at compile time, link time, load time, or at the time their living environment is created; and they are deleted when the whole system, or their living environment dies. Java preserves this nature only for primitive objects, which is not enough for many application that care about the memory efficiency.

Transframe provides a generic object reference framework, and from which different object reference protocols can be derived as subclasses.

By default, references to primitive objects are static ones and they are assigned with values by direct copy; references to composite objects are smart ones unless you decide that they must be statically allocated.

Transframe enables user to define their own object references to deal with issues like system resource or persistent objects. Here is an example.


    class Handle is Refential #(ObjectType: type of OSResource)
    {
	function operator.(): ObjectType;
		 // get the object referred by the handle
	function operator share (Handle);
		 // operator used by share reference assignmnet
	enter()  // constructor 
	{        // create the resource and return the handle 
	};
	exit()   // destructor
	{        // collect the resource (may use the similar GC techinique 
	};
    };

Consider the following code written by a user:
    class PaintWindow is Window
    { private:
	my_brush:  Handle of Brush; // or Handle#(Brush)
	my_canvas: Handle of Canvas;
      public:
	function paint ()
	{
	    with (my_brush)
	    {    setStyle (Crayon);
	         setColor (NavyBlue);
	    }
	    // paint something with the brush on the canvas
	};
	enter () : Window()   // constructor
	{
	    my_brush := (Handle of Brush) ();   // create a brush
	    my_canvas := (Handle of Canvas) (); // create a canvas
	}
    };

Handle is such a smart object reference that you do not need to deallocate the associated resource. When a paint window is to be destroyed, the destructor of its member object will be called first. In this case, the destructor of brush handle and canvas handle will be called, and the operating system will free the resource if the paint window didn't borrow its resources to others for share in terms of using assignment.

Note that setStyle and setColor are member functions (classes) defined in the class Brush. Using "." operator, we get the object pointed by the reference, and then select the member of the object:

	my_brush.setStyle(Crayon)
In Transframe, operators like &, *, -> are not required. There is no tricky C++ expressions like "&(**x)->foo()". There is no confusion between expressions "new C()" and "C()". There is no need to "delete". There is even no need to "finalize" for high-level users. Object references of all types have a simple and uniform interface for usage; in general, only ":=" for assignment, and "." for member selection.
Exercise 1:
Exercise 2:

For further reading, check out David Shang's article: Access to Objects, and see how Transframe provides a generic referential framework; so that objects, no matter where it is stored, can be accessed safely without a worry about resource-leek.



[ Go back to tutorial | Tutorial home page | Transframe home page ]

More examples: