3.3 Anonymous Objects


In some cases an object is needed only temporarily. Explicitly introducing a variable to name this temporary object can be avoided by creating an anonymous object, which is an object in every sense except that it has no name. Consider the following example:

  Location initialLocation(100, 100), 
            displayLocation(200,200);

   Shape    initialShape(150, 200), 
            displayShape(300, 200);

   Frame window  (initialLocation, initialShape);
   Frame display (displayLocation, displayShape);
 
   ...

   Location newLocation(300,300);
   Location newShape   (150,150);

   window.MoveTo(newLocation);
   display.Resize(newShape);


Assume that all of the Location and Shape objects have no other uses than the ones shown in the example.

Using explicitly declared and named objects that are used only once has several disadvantages. First, the programmer has to write a separate declaration and invent a meaningful name for an object that plays a very minor, perhaps trivial role. This effort may not be seen as worthwhile. Second, the object may continue to exist for some time after it has been used even though it is not needed. In the above example, the scope of "initialLocation" and "window" are the same. However, the window object may be needed far longer than the Location object, though both objects will continue to exist. It is a more efficient use of memory to be able to delete the Location object as soon as its useful lifetime has ended. Third, the reader of the code is not given a clear indication that objects such as "initialLocation" and "displayLocation" are, in fact, used in such a localized way. Only by reading all of the code in this scope can it be determined whether those objects are used only once or again later.

Anonymous objects are a more efficient and clearer way to create and use an object that is needed only to be used in a single, localized place. An anonymous object is constructed directly in the place where it is needed.

The example above can be re-written using anonymous objects as follows:

   Frame window  ( Location(100,100), Shape(150, 200) );
   Frame display ( Location(200,200), Shape(300, 200) );
 
   ...

 
   window.MoveTo( Location(300,300) );
   display.Resize( Shape(150,150) );


In the construction of the window object, two anonymous objects are created: one anonymous Location object and one anonymous Shape object. The display object is also created using two anonymous objects. Finally, the MoveTo and Resize operations use anonymous objects as well. It is important to realize that the example with named objects and the one with anonymous objects each have exactly the same observable effects.

Anonymous objects are also useful in providing the default value for a parameter that is an object of a class rather than a built-in type. For example, the MoveTo method in the Frame class takes a Location object as its parameter. If a default value was desired for this parameter, it could be specified as follows:

  class Frame {
    private:
     ...
    public:
     ...
        void MoveTo (Location loc = Location(10,10)); 
     ...
   };

This definition of the MoveTo method specifies that if the MoveTo method is invoked with no arguments, then the default Location of (10,10) will be used.

Moreover, anonymous objects are used in assigning a new value or updating the value of an object. Suppose that a Frame object named "window", has been created using a Location object, named "current." The Frame is to be shifted by a relative amount (five pixels in each direction) on the screen. What is needed is a way to update the Location object. However, the Location class does not define any mutator methods that allow Location objects to be updated - they can only be constructed and examined. Three different ways of using anonymous objects are shown in the following code examples.

  // First example  

   Location current(100,100);
   Frame window  (current);
 
   ...
 
   window.MoveTo( Location(current.XCoord()+5, current.YCoord()+5) );


This first example shows that an anonymous object can be constructed from an existing object. In this case the current Location object is queried using the accessor methods defined in the Location class and the results are used to define the constructor arguments for a new, anonymous Location object.

  // Second example  

   Location current(100,100);
   Frame window  (current);
 
   ...
   current = Location(105,105);
   window.MoveTo( current );


In the second example, an anonymous object is created with the new coordinates and is assigned to the object named current. Object assignment is a simple, byte-level copy operation: each object resides in a block of memory. The default assignment operation overwrites the bytes in the block of memory holding the object on the left-hand side of the assignment (current) with the bytes copied from the right-hand side of the assignment. In this sense, default object assignment is exactly similar to the assignment "x = 10" that overwrites the memory holding the value of the variable x with the bit pattern that represents the value 10.

  // Third example  

   Location current(100,100);
   Frame window  (current);
 
   ...
   current = Location(current.XCoord()+5, current.YCoord()+5);
   window.MoveTo( current );


The third example uses an assignment among objects that mirrors the familiar assignment of ordinary variables such as "x = x + 1" where the value of the exisiting variable is used to compute a value that is then assigned as the new value of the variable. In the same way, the value of the object current is queried, using the accessor methods defined by the Location class, and a value is computed (the anonymous Location object) that is then assigned as the new value of the current object. This example differs from the second example in that it is not necessary to know the absolute coordinates of the new Location - the new value of the Location object is computed relative to the existing value of the object.

Notice that anonymous objects remove the three problems noted above. First, no separate declaration is needed for the anonymous objects. They are simply created at the site of use without the need for an identifier name. Second, the object is constructed only when its needed and destructed as soon as its immediate use is over. This reduces to a minimum the lifetime of the anonymous object and reduces its resource usage. Third, it is clear to the reader that the anonymous object is not used elsewhere - such other usage being impossible since there is no way to refer to the object.

Tasks

  1. Using only anonymous objects, write a declaration for a Frame object that is located at the coordinates (50,50) and has a width of 200 and a height of 300.

  2. Using only an anonymous object, write the line of code to move a Frame identified by the variable name "window" to the coordinates (100,100).

  3. Using only an anonymous object, write the line of code to resize a Frame identified by the variable name "window" so that it has a width of 200 and a height of 300.

  4. Suppose that a Frame object identified by the variable name "window" is currently located at the coordinates given by the Location object identified by the variable name "position". Using an anonymous object, write a single line of code that moves the Frame object 10 pixels to the right and 50 pixels down.

  5. Suppose that a Frame object identified by the variable name "window" currently has the dimensions given by the Shape object identified by the variable name "size". Using an anonymous object, write a single line of code that changes the dimensions of the Frame object to be 50 pixels wider and 50 pixels shorter.

 




©1998 Prentice-Hall, Inc.
A Simon & Schuster Company
Upper Saddle River, New Jersey 07458

Legal Statement