Program 3

Class Declarations

The three classes in the employee hierarchy are defined below. Notice that HourlyEmployee and FlatRateEmployee both are declared as :public Employee. This indicates that both are children of the class Employee. The enumerated values HOURLY and FLATRATE are used to document the type of class we are writing to the file. Enumerated items assign the number 0 to the first listed item, 1 to the second and so on unless the programmer makes assignments to these items. The rest of these definitions should look familiar.

class Employee 
{
public:
	enum {HOURLY, FLATRATE};
	// There is no object of type Employee, so the functions are dummies
	void write (ostream&){}
	void read(istream&){}
	void print(){}
};
class HourlyEmployee :public Employee
{
public:
	HourlyEmployee();
	HourlyEmployee(const string &,int);
	void write (ostream&);
	void read(istream&);
	void print();
private:
	string _name;
	int _hours;
};

class FlatRateEmployee :public Employee
{
public:
	FlatRateEmployee();
	FlatRateEmployee(const string &);
	void write (ostream&);
	void  read(istream&);
	void print();
private:
	string _name;
};

The File Structure

Before we can write the code for the various classes we must consider the structure of the file. In a file with more than one type of object, it is important to indicate at the beginning of each item which class it belongs to. In this case 0 (Employee::HOURLY) indicates an hourly employee while 1 (Employee::FLATRATE) indicates a flat rate employee. The file used in this program is given below.

5
0
Joe Hardluck
20
1
Big Cheese
0
Sleepy Weepy
10
1
Medium Cheese
0
Poor Cousin
34

When a given employee writes itself to the file, it first identifies what type of employee it is. This means when the run function (or whichever function reads the file) reads this file, it first reads the type of object, creates that type of object, then has the object read itself. In run this leads to the following code section:

	int size;
	in >> size;
	for(int i = 0;i < size; i++)
	{
		int type;
		in >> type;
		if (type == Employee::HOURLY)
		{
			HourlyEmployee e;  
			e.read(in);
			e.print();
			cout << endl;
		}
		else
		{
			FlatRateEmployee e;
			e.read(in);
			e.print();
			cout << endl;
		}
	}

Outside of the method used for reading the employee and printing their record, notice the form of the conditional. In c++ like c, conditionals take the form:

if ( < integer expression> )
	statement
The integer expression can be any expression that has a value that converts to an integer. In this case we want to test if the type of the object is HOURLY so we write
if (type == Employee::HOURLY)

The == sign is the test for equality and the result of this operation is either 1 or 0 depending on weather or not the two things being compared are equal or not. It is a common mistake to write

if (type = Employee::HOURLY)
type = Employee::HOURLY is in fact an integer expression whose value is the value of the item on the right of the operator. This is usually an error, so the compiler will flag this with a warning. If your programs have warnings you will lose points, so make sure you don't try using a tricky assignment to both assign and test.

The Class Code

Most of the code is pretty much the same as what you have seen before. There are two things that are new. First when writing an object, the type of the object is written first as you see in FlatRateEmployee::write.

void FlatRateEmployee::write(ostream &out)
{
	out << FLATRATE << endl;
	out << _name << endl;
}

This is also the first time you have some fancy output. The pay is a double, and therefor would normally be written in scientific notation. To avoid having monetary output look like the number of atoms in the universe, we must set the output stream to write in dollars and cents. This is done by setting precision to 2 and the output flag (setf) to ios::fixed (this is another enumerated object defined within a class). You will also notice that by starting the string "wage: $" with "\t" this string is tabbed.

void FlatRateEmployee::print()
{
	cout.precision(2); // two place accuracy on output
	cout.setf(ios::fixed);// fixed point notation
	cout << "Name: " << _name << "\twage: $" << 567.32;
}

For a complete copy of this program click here.

Back to Week 2