3.6 Objects as Return Values




A method of a class may return as its result an object that is of a class different from the class of the object performing the method. Some examples of methods that return objects from other classes are the following:

The first example is one where an object (a Frame) yields some information about itself (its Location or Shape) by returning an object that bears that information. This is done by an object because the data is not a simple built-in type. The second example is one where the returned object (a File) has been generated by the returning object (a FileQuery). Both of these example will be illustrated in more detail below.

The Frame class will be revised to add methods for a Frame to return its Location and Shape. The revised class definition is:


  class Frame {					// Version 6
     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 Frame
     void     Resize(Shape    newShape);	// change shape of Frame
     void     Resize(float factor);		// grow/shrink by factor
     Shape    WhatShape();              	// reply current shape
     Location WhereAt();			// reply current location

   };

The two new methods (WhatShape and WhereAt) return Shape and Location objects. These methods can be used as follows:

   Frame window (nearCenter, largeSquare);

   // assume user moves or resizes the window 

   Shape    currentShape    = window.WhatShape();
   Location currentLocation = window.WhereAt();


The second example of classes returning objects from different classes involves the two new classes mentioned above: File FileQuery.

The File class captures the notion of a named, viewable body of text stored in the file system. The definition of the class is as follows:

  class File {
  private:
				// encapsulated implementation goes here
  public:

       File(char* fileName);               // represents file with given name
       File();                             // unknown, as yet, file
 char* Name();                             // reply name of file
 int   Exists();                           // does file Exist?
 void  View();                             // scrollable view window
 void  Edit(char* editor);                 // edit file using "editor"
 void  Delete();                           // delete from file system (gone!)
      ~File();                             // free name
};

The constructor allows the file to be given a name and the Name method allows that name to be queried. Because a file object may be created and not bound to a name and to guard against a user enterin the name of a non-existant file, the Exists method returns a value indicating if the file exists in the file system.

The View method opens a window on the screen within which the file is viewable. The user is able to scross horizontally and vertically through the file. The file can only be viewed, it cannot be changed. The file can be edited using the Edit method that takes as its parameter the name of the editor to be used to perform the editing. The file can be removed from the file system using the Delete method. After the Delete method has executed, the File object still exists, but the file itself does not.

The FileQuery class initiates a dialog with the user. The user is prompted to enter the name of a file. The FileQuery object returns a File object that represents the file named by the user. The FileQuery class is defined as follows:

 class FileQuery {
 private:
			// encapsulated implementation goes here

 public:

        FileQuery( char* path, char* filter );    // prompt with path and filter
        FileQuery( char* path );                  // prompt with path default filter
        FileQuery( );                             // use all defaults
   File AskUser();                                // get file from user via dialog
  ~FileQuery();
};
The constructors of the FileQuery allow a directory path (e.g., "/home/user") and a pattern for the expected file name. The pattern uses the traditional Unix "wild card" symbols. For example, the filter "*.ps" would describe any file with a ".ps" suffix. If not give, the path defaults to the current working directory and the filter defaults to any file (i.e., "*").

The FileQuery is very permissive. The path and filter information is provided as hints to the user, but they are not enforced. The user is free to enter any file name. Alternative, more restrictive and safer methods for soliticing a file name from the user are seen shortly.

The principle member function of the FileQuery class is the AskUser method. This method returns a File that is associated with the name entered by the user in the dialog initiated by the AskUser method.

An example of using the File and FileQuery class is the following:


   FileQuery query("/home/kafura", "*.ps");

   File file = query.AskUser();
   file.View();

In this example, the FileQuery object conducts the interaction with the user and returns a File object that is then presented to the user for viewing.

Objects of a given class may be returned from more than one other class. The FileQuery class defined above is only one way in which a File object may be produced as a result of a dialog with the user. The weakness of the technique used by the FileQuery class is that it relies heavily on the user's memory to recall to the name of the file and the error-free entering of that name by the user.

Two other classes for producing File objects use choosing and navigating techniques. Choosing means that the user is presented a list of files among which exactly one is chosen. Navigating means that the user is able to traverse the file tree in search of the desired file. The two classes below for choosing and navigating use a path name for the directory and a filter.

The FileChooser and FileNavigator classes are defined as follows:

   class FileChooser {
     private:
				// encapsulated implementation goes here
     public:

         FileChooser(char* path, char* filter);   // search at path with filter
         FileChooser(char* path);                 // search at path, no filter
         FileChooser();                           // search at CWD, no filter
    File AskUser();                               // get file via dialog
        ~FileChooser();                           // clean up
   };

   class FileNavigator {
     private:
				// encapsulated implementation goes here
     public:
         FileNavigator(char* path, char* filter);   // start at path using filter
         FileNavigator(char* path);                 // start at path, no filter
         FileNavigator();                           // start at CWD, no filter
    File AskUser();                                 // get file via dialog
        ~FileNavigator();                           // clean up
   };
An important aspect of object-oriented programming is seen in the public interfaces of the three classes FileQuery, FileChooser and FileNavigator: except for the difference in their names, they all have the same interface. The constructor arguments are the same as is the AskUser method. Each class provides the same functionality to the program though each achieves its functionality in a distinct way. However, the similarity of these classes does not allow them to be used transparently by the program. Due to the type checking, it is not possible, using the C++ language that we have seen so far, to interchange one with the other without rewriting the source code. We will see later that there are effective ways to organize and manipulate classes that have such similarity.

Exercises


  1. Write a program that edits a file whose name was selected by the user using the FileQuery class.

  2. Write a program that edits a file whose name was selected by the user using the FileChooser class.

  3. Write a program that edits a file whose name was selected by the user using the FileNavigator class.

  4. Write a program that deletes a file whose name was selected by the user using the FileNavigator class.

Last Updated: August 21, 1995 / kafura@cs.vt.edu