Handout 24a

Another Inheritance Example*

(revised 29NOV2000)


This program illustrates multiple inheritance by creating a student work class which inherits from person, student, and worker. The relationships among the classes can be visualized as:

This example also introduces the concepts of:


#include <iostream.h>
#include <iomanip.h>
#include <new.h>
#include <string.h>

class person {
private:
        char * name;
        int age;
        char * phone_number;
public:
        // default constructor
		person() { 
                name = new char[strlen("UNKNOWN")];
                strcpy(name, "UNKNOWN");
                phone_number = new char[strlen("555-1212")];
                strcpy(phone_number, "555-1212");
        }
		// three parameter constructor
        person(const char inName[], const char inPhone[], const int inAge) {
                name = new char[strlen(inName)];
                strcpy(name, inName);
                phone_number = new char[strlen(inPhone)];
                strcpy(phone_number, inPhone);
                age = inAge;
        }
        ~person() {
                delete [] name;
                delete [] phone_number;
        }
        char * get_name();
        char * get_phone();
        int get_age();
};

char * person::get_name() { 
	return name; 
}

char * person::get_phone() { 
	return phone_number; 
}

int person::get_age() { 
	return age; 
}

////////////////////////////////////////////////////////////////////////////////

class student : public virtual person {// virtual to prevent multiple subobjects
private:
		static int next_student_id; // used to generate unique student id's
        const static int low_A;
        const static int low_B;
        const static int low_C;
        const static int low_D;
        int id_num; // student number (created from next_student_id)
        float final_average; 
public:
        // default constructor
		student() {
                final_average = 0;
                id_num = next_student_id++;
        }
        // one parameter constructor
		student(float avg) {
                final_average = avg;
                id_num = next_student_id++;
        }


        int id();
        int average();
        char letter_grade();
};

int student::id() { 
	return id_num; 
}

int student::average() { 
	return (int) final_average; 
}

// some constants used in the student class
int student::next_student_id = 0;

const int student::low_A = 90;
const int student::low_B = 80;
const int student::low_C = 70;
const int student::low_D = 60;

char student::letter_grade() {
        if (final_average >= low_A)
                return 'A';
        else if (final_average >= low_B)
                return 'B';
        else if (final_average >= low_C)
                return 'C';
        else if (final_average >= low_D)
                return 'D';
        else
                return 'F';
}

////////////////////////////////////////////////////////////////////////////////

class worker : public virtual person {// virtual to prevent multiple subobjects
        float hours_worked_this_week;
        float pay_rate;
public:
        // default constructor
		worker() {
                hours_worked_this_week = 0;
                pay_rate = 5.0;
        }
		// one parameter constructor
        worker(float hours) {
                hours_worked_this_week = hours;
                pay_rate = 5.0;
        }
        void set_hours(float hours);
        void set_rate(float rate); ;
        float overtime_hours(); 
        float pay(); 
};

void worker::set_hours(float hours) { 
	hours_worked_this_week = hours; 
}

void worker::set_rate(float rate) { 
	pay_rate = rate; 
}

float worker::overtime_hours() {
	return (hours_worked_this_week > 40 ? hours_worked_this_week - 40 : 0);
}

float worker::pay() {
	if (overtime_hours() > 0)
		return pay_rate * (40.0f + 1.5f * overtime_hours());
	else
		return pay_rate * hours_worked_this_week;
}

////////////////////////////////////////////////////////////////////////////////

class student_worker : public student, public worker {
public:
        // 4 parameter constructor
		student_worker(const char name[], const char phone[],
                       const int age, const float average)
					   // initialize student and person subobjects
					   : student(average), person(name, phone, age) {} 

        // 5 parameter constructor
		student_worker(const char name[], const char phone[],
                       const int age, const float average,
                       const float hours)
				// initialize student, person and worker subobjects
                : student(average), person(name, phone, age), worker(25.0) {}
};

////////////////////////////////////////////////////////////////////////////////

const int numb_proctors = 5;

int main() {

        // create an array of pointers to student workers
		student_worker * proctor[numb_proctors];

        proctor[0] = new student_worker("Foghorn Leghorn",
                                        "1.800.farmboy", 2, 87, 12);

        proctor[1] = new student_worker("Tom Terrific",
                                        "555-1212", 11, 94);
        proctor[1]->set_hours(60);
        proctor[1]->set_rate(4.25);

        proctor[2] = new student_worker("Penelope Pitstop", "x1234", 23, 83);
        proctor[2]->set_hours(40);
        proctor[2]->set_rate(10.50);

        proctor[3] = new student_worker("Dick Dastardly",
                                        "1.888.hopeful", 38, 73);
        proctor[3]->set_hours(30);
        proctor[3]->set_rate(1.50);

        proctor[4] = new student_worker("Mutly", "1.888.hopeles", 6, 81, 20);


        cout << "Name               ID #   Grade    Pay\n"
             << "----------------   ----   -----    ---\n";
        for (int i = 0; i < numb_proctors; i++) {
                cout << setw(16) << setfill(' ') << proctor[i]->get_name()
                     << "  " << setw(6) << setfill('0') << proctor[i]->id()
                     << "    " << proctor[i]->letter_grade() << "    ";

                cout.setf(ios::fixed, ios::floatfield);
                cout << setw(6) << setfill(' ') << setprecision(2)
                     << proctor[i]->pay() << '\n';
        }

        return 0;
}

/* program output

Name               ID #   Grade    Pay
----------------   ----   -----    ---
 Foghorn Leghorn  000000    B    125.00
    Tom Terrific  000001    A    297.50
Penelope Pitstop  000002    B    420.00
  Dick Dastardly  000003    C     45.00
           Mutly  000004    B    125.00

*/


* example based on one from here.