In-Class Exercise
Functions in a Hierarchy
This exercise improves the structure of an inheritance hierarchy.
Given Information
The following code is a solution to
the Handout on Derived Classes.
Client Module
The client program is listed on the left and the output is shown on the right
// Client Program
// h12.cpp
#include <iostream>
#include "Employee.h"
int main() {
Employee employee(1234, "Jane Doe", 15.50);
employee.display(std::cout);
std::cout << std::endl;
}
|
Jane Doe (1234) $15.50
|
Employee Module
Employee.h
The header file contains the definition of the base class
and the derived class:
// Derived Classes
// Employee.h
#include <iostream>
const int MAX_NAME = 20;
class Person {
char name[MAX_NAME + 1];
public:
Person();
void set(const char*);
void displayName(std::ostream&) const;
};
class Employee : public Person {
int no;
double rate;
public:
Employee();
Employee(int, const char*, double);
void display(std::ostream&) const;
};
|
Employee.cpp
The implementation file
contains the function definitions for both classes:
// Derived Classes
// Employee.cpp
#include <iomanip>
#include <cstring>
#include "Employee.h"
Person::Person() {
name[0] = '\0';
}
void Person::set(const char* n) {
strncpy(name, n, MAX_NAME); // copy first MAX_NAME characters
name[MAX_NAME] = '\0'; // ensure that last byte is null
}
void Person::displayName(std::ostream& os) const {
if (name[0] != '\0')
os << name << " ";
}
const double MIN_WAGE = 10.25;
const int SAFE_NUM = 0;
Employee::Employee() {
// safe empty state
no = SAFE_NUM;
rate = MIN_WAGE;
}
Employee::Employee(int n, const char* nm, double r) {
if (n > SAFE_NUM && r >= MIN_WAGE) {
no = n;
set(nm);
rate = r;
} else {
Employee temp;
*this = temp;
}
}
void Employee::display(std::ostream& os) const {
if (no != SAFE_NUM) {
displayName(os);
os << std::fixed << std::setprecision(2);
os << "(" << no << ") $" << rate;
}
else
os << "no data available";
}
|
Your Task
Client Module
The upgraded client program accesses the base class
as well as the derived class:
// Functions in a Hierarchy
// h13.cpp
#include <iostream>
#include "Employee.h"
int main() {
Employee employee(1234, "Jane Doe", 15.50);
Person person("John Doe");
employee.display(std::cout);
std::cout << std::endl;
person.display(std::cout);
std::cout << std::endl;
}
|
Jane Doe (1234) $15.50
John Doe
|
Employee Module
Upgrade the Employee module to accept the
employee's name through a base class constructor and to admit calls to
display() member functions on both classes:
- replace the set() member function in the
Person class with a one-argument constructor
that receives the address of a C-style null-terminated string.
The constructor copies the name stored at that address into the
data member
- change the name of the displayName()
query to
display()
- call the display()
query in the Person class from the
display() query in the Employee
class
Employee.h
// Functions in a Hierarchy
// Employee.h
#include <iostream>
const int MAX_NAME = 20;
class Person {
char name[MAX_NAME + 1];
public:
Person();
};
class Employee : public Person {
int no;
double rate;
public:
Employee();
Employee(int, const char*, double);
void display(std::ostream&) const;
};
|
Employee.cpp
// Functions in a Hierarchy
// Employee.cpp
#include <iomanip>
#include <cstring>
#include "Employee.h"
Person::Person() {
name[0] = '\0';
}
(const char* n) {
strncpy(name, n, MAX_NAME);
name[MAX_NAME] = '\0';
}
void Person:: (std::ostream& os) const {
if (name[0] != '\0')
os << name << " ";
}
const int MIN_WAGE = 10.25;
const int SAFE_NUM = 0;
Employee::Employee() {
// safe empty state
no = SAFE_NUM;
rate = MIN_WAGE;
}
Employee::Employee(int n, const char* nm, double r)
{
if (n > SAFE_NUM && r >= MIN_WAGE) {
no = n;
rate = r;
}
else { // safe empty state
Employee temp;
*this = temp;
}
}
void Employee::display(std::ostream& os) const {
if (no != SAFE_NUM) {
os << std::fixed << std::setprecision(2);
os << "(" << no << ") $" << rate;
}
else
os << "no data available";
}
|
|