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