3.2 Objects as Parameters 
 
The examples that follow make use of two new classes. In the original
definition of the Frame class the location and shape of the frame were
described by four integer values. Both of these concepts, however, can
be captured in classes as follows:
 
   class Location {			// Version 1
     private:  
	// encapsulated implementation goes here
     public:
	Location(int x, int y);		// specific location
        Location();			// default location
     int Xcoord();			// return x-axis coordinate
     int Ycoord();			// return y-axis coordinate
   };
   class Shape {			// Version 1
     private:  
	// encapsulated implementation goes here
     public:   
	Shape(int width, int height);	// specific shape
	Shape();			// default shape
     int Height();			// return height
     int Width();			// return width
   };
 
The methods Xcoord, Ycoord in the Location class and Height and Width in the
Shape class are often called "accessor" methods because they allow you to
access, albeit indirectly, some information about the state of the object.
These new class can be used as follows:
 
   Location nearTop(20, 20), nearCenter(500, 500);
   Shape    smallSquare(50, 50);
   Shape    largeSquare(500, 500);
   
 
These two classes have two advantages (five more will be seen
shortly). First, they capture the concept of "location" and
"shape". This is largely what "real" object-oriented programming is
about - building classes that capture the concepts of some
application. A good class need not be one that has an "important
looking" interface. The Location and Shape classes are modest ones
that cleanly capture a simple, but useful, concept.  Second, the
declarations above show that named objects can convey useful
information to the reader about the intention of the programmer.  The
name "largeSquare" is more suggestive about the intention to have a
window that is large and square than are the two integers 500 and 500
used in a parameter list with two other integers and one or more other
values.
The Frame class can now be redefined to use the definitions of Shape and
Location as follows:
 
  class Frame {				// Version 3
     private:  
          // encapsulated implementation goes here
     public:
	  Frame(Location p, Shape s);	// exact description
	  Frame(Shape s, Location p);	// exact description
	  Frame(Location p);		// default shape
	  Frame(Shape s);		// default location
	  Frame();			// all defaults;
     void MoveTo(Location newLocation); // move the window
     void Resize(Shape    newShape);	// change shape
     void Resize(float factor);		// grow/shrink by factor
   };
 
The third advange of defining the Shape and Location classes is seen in the
first two overload constructors. Since Shape and Postion are distinguished
classes it is possible to define constructors that take them in either 
order. This cannot be done when the shape and location information is
represented by four integer values. The fourth advantage is seen
in the overloaded constructor "Frame(Shape s);". Such a constructor
did not (and could not) exist in the earlier version (Version 2) of
the Frame class. When the location and shape information is
represented as four integers, what does a constructor with only two
integers mean?  Depending on how the four arguments are ordered it
means either that the shape is missing or the location is missing, but
it cannot mean both!  However, both overloading are possible by
introducing different classes that distinguish the two integers that
are the shape from the two integers that are the location.
Frame objects can be created as follows:
 
   Frame  smallTop    (nearTop,    smallSquare);
   Frame  largeCenter (nearCenter, largeSquare);
   Frame  someWhere   (largeSquare);
   Frame  someSize    (nearCenter);
   Frame  anyKind;
 
These declaration of Frame objects illustrate the last three advantages of
the Shape and Location classes. Fifth, the declarations are much more
readable with the Shape and Location classes than without. Sixth, the
Shape and Location objects (e.g., largeSquare and nearCenter) can be
reused, avoiding the addition programming effort of remembering the exact
coordinates of the "near to the center" point. Seventh, by changing the
declaration of the Shape and Location objects (e.g., nearTop) the declarations
of the Frames will then be adjusted accordingly. It is not necessary to go
through the code looking for all the declaration of Frame objects and
changing their integer parameters.
The Location class has uses beyond those for which it was immediately conceived.
Since the Location class captures a reasonably abstract notion - a point in a
two dimensional coordinate system - it may be useful anywhere such a coordinate
system appears. For example, just as the Location class helps to record "where on
the screen should a window be placed" it can also be used by other interface
items to record "where within a window should an icon be placed".
The Message class is a simple user interface element that can be placed at a location
within a window. The definition of this class is:
   class Message {
   private:
		// encapsulated implementation goes here
   public:
      Message(char* text, Location p);       // Message with text at Location p
      Message(char* text);                   // Message with text a default Location
     ~Message();                             // delete message
   }; 
The Message class uses the Location class in its first constructor to determine where
within a window the text of the message is to appear.
The Frame class is extended again to provide a means for placing a Message object in
a window. The extended definition is:
 
  class Frame {				// Version 4
     private:  
          // encapsulated implementation goes here
     public:
	  Frame(Location p, Shape s);	// exact description
	  Frame(Shape s, Location p);	// exact description
	  Frame(Location p);		// default shape
	  Frame(Shape s);		// default location
	  Frame();			// all defaults;
     void MoveTo(Location newLocation); // move the window
     void Resize(Shape    newShape);	// change shape
     void Resize(float factor);		// grow/shrink by factor
     void Display(Message msg);		// show msg in window
   };
 
The following code shows how the Location class is used in creating a Frame object
and a Message object:
//Declarations
   Location windowLocation(50, 50);
   Location msgLocation(10, 10);
   Frame window(windowLocation, Shape(100, 200);
   Message msg("Hello World!", msgLocation);
// code
   window.Display(msg);
  
 |  Exercises  | 
- Give at least two other good names that could be used for the Shape
     class. 
 - Give at least two other good names that could be used for the Location
     class. 
 - Give at least two other good names that could be used for the Message
     class. 
 - Give the declarations of at least four Location objects that are on the
     top and left-hand side of the display. 
 - Give the declarations of at least four Shape objects that are thin
     rectangles that are short or long in length. 
 - Give the declarations or at least four Frame objects that use different
     combinations of the Location and Shape objects defined in the last two
     questions. 
 - Draw a picture of a screen showing how the Frame object declared in the
     last question would appear on the screen. Label each Frame in the
     picture with the name of the object that it represents. 
 - Write a program that creates a 200 by 200 size window near the middle of
     the screen with your complete name displayed near the middle of that 
     window. 
 - 
     Write a program that creates a 200 by 200 size window near the middle of
     the screen with your first name centered at the top of the window and your 
     last name centered at the bottom of the window. 
 
 Last updated: August 21, 1995  /  kafura@cs.vt.edu