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);



Next Stop


Exercises

  1. Give at least two other good names that could be used for the Shape class.

  2. Give at least two other good names that could be used for the Location class.

  3. Give at least two other good names that could be used for the Message class.

  4. Give the declarations of at least four Location objects that are on the top and left-hand side of the display.

  5. Give the declarations of at least four Shape objects that are thin rectangles that are short or long in length.

  6. 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.

  7. 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.

  8. 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.

  9. 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