Tom Kelliher, CS23
Apr. 29, 1996
Final project: Project 25, pg. 554.
Quiz, on today's material (including lab), on Wednesday.
Schedule for remainder of semester:
This program is on the homepage, and also available from
~kelliher/public_html/cs23/virtual.cc
.
/********************************************************************** * virtual.cc * Tom Kelliher * * This program demonstrates several advanced features of classes: * o Abstract base classes and pure virtual functions. * o Virtual functions, polymorphism, and late binding. * o Static class members. * o Friend functions. * * The program defines class person as an abstract base class. Class * employee is derived from this class, and class manager is derived * from class employee. * * All persons are linked together through the static data member list * of person. A print() member function must be defined for all * classes derived from class person. The function printList() * traverses the list, calling print() on each person in the list. * Because print() is virtual, it is polymorphic. **********************************************************************/ // Comment out the following #define to make printList() a member // function of class person. Otherwise, it will be a friend of class // person. #define FRIEND #include <iostream.h> #include <stdlib.h> /********************************************************************** * class person **********************************************************************/ class person { #ifdef FRIEND friend void printList(void); #endif // Allow derived classes direct access. protected: char* name; int age; // Pointer to next person on list. person* next; // Head pointer to persons list. Because it is static, only one // all class variables *share* it. static person* list; public: person(char* name, int age); virtual void print(void) = 0; #ifndef FRIEND static void printList(void); #endif }; // Static class data members can only be initialized at file scope. person* person::list = NULL; /********************************************************************** * person::person() * * Preconditions: name is a string, age is a non-negative integer. * * Postconditions: Person is initialized with the given name and age. **********************************************************************/ person::person(char* name, int age) : name(name), age(age) { next = list; // Add the new person to the beginning of the list. list = this; } /********************************************************************** * printList() || person::printList() * * Preconditions: None. * * Postconditions: The list of persons is printed. **********************************************************************/ #ifdef FRIEND void printList(void) #else void person::printList(void) #endif { person* pp; for (pp = person::list; pp != NULL; pp = pp->next) pp->print(); } /********************************************************************** * class employee **********************************************************************/ class employee : public person { private: char* company; public: employee(char* company, char* name, int age); void print(void); }; /********************************************************************** * employee::employee() * * Preconditions: Company and name are strings, age is a non-negative * integer. * * Postconditions: The new employee is initialized. **********************************************************************/ employee::employee(char* company, char* name, int age) : person(name, age), company(company) { } /********************************************************************** * employee::print() * * Preconditions: None. * * Postconditions: The employee data is printed. **********************************************************************/ void employee::print(void) { cout << "Employee: " << name << endl; cout << "Company: " << company << endl; cout << "Age: " << age << endl << endl; } /********************************************************************** * class manager **********************************************************************/ class manager : public employee { private: char* dept; public: manager(char* dept, char* company, char* name, int age); void print(void); }; /********************************************************************** * manager::manager() * * Preconditions: Department, company, and name are strings, age is a * non-negative integer. * * Postconditions: The new manager is initialized. **********************************************************************/ manager::manager(char* dept, char* company, char* name, int age) : employee(company, name, age), dept(dept) { } /********************************************************************** * manager::print() * * Preconditions: None. * * Postconditions: The manager data is printed. **********************************************************************/ void manager::print(void) { cout << "Manager of department: " << dept << endl; employee::print(); } /********************************************************************** * main() **********************************************************************/ int main() { employee e("Amalagated Widgets", "Bob", 13); manager m("Widgets", "Amalagated Widgets", "Jane", 15); #ifdef FRIEND printList(); #else person::printList(); #endif cout << "**************************************************\n\n"; manager mm("Assorted Baubles", "Baubles, Inc.", "Tony", 3); employee ee("Baubles, Inc.", "Pam", 1); #ifdef FRIEND printList(); #else person::printList(); #endif }
Grab a copy of the program and try/answer the following:
virtual void print(void) = 0;to
void print(void) {}What does that accomplish? Predict the output from the modified program. Reconcile your predicted output with the actual output.
Replace the modified line with the original before moving on to the next exercise.