Well since most of you program all day, the last thing you probably want to do is look at code. But if you are bored to death, I'm taking a Design Patterns class using C++, and I am trying to learn C++ (coming from C) and also trying to learn design patterns (factory method in this case). If you feel like tearing me apart, please have at it. I have listed the assignment, and my solution (which I have already turned in) at the bottom (Visual C++ 2008 Express). It runs, produces good output (I think) but I don't know about my C++ style.
Any feedback you can give me would be appreciated, even if just glancing at my code and seeing if something looks extremely amateurish.
P.S. How do I format code for posting?
=================== the assignment =======================================
Objectives: the assignment uses
• inheritance,
• polymorphism,
• virtual functions,
• protected data members,
• files streams,
• operator overloading,
• the “Factory Method” design pattern
The Jones Company wants a single computer program that performs payroll calculation for salaried, hourly, and commissioned sales personnel. To minimize coding and maintenance, it is decided to combine common characteristics of all employees in to a base class named Employee. From it are to be derived three classes: Salaried, Hourly, and Commission. Each of these classes contains data specific to the employee type. Salaried has a double variable named salary. Hourly has doubles rate and hours while Commission has a double named sales. Employee has a char[12] called EmpID, a char[5] named DeptID and a double called net, representing the net pay of all derived classes.
Each class is responsible for reading and writing its own data. That means that Employee must read and write EmpID and DeptID, Salary must read and write salary and so on. The ONLY exception to this rule is “net” from Employee. The derived classes must both calculate the correct value for net and print it as part of their output.
In “main”, you are allowed to create ONE object only. In fact, in the entire program, you may instantiate only ONE object. Using polymorphism, share the object for all employees regardless of type. Write a “Factory Method” to create the objects to assigned to “the” object.
All input is from a data file. The file stream must be passed to each class that needs to read from it. Remember that the file variable should be a reference, otherwise the file pointer will not progress and you program will loop infinitely. On the back is a sample file and output.
Virtual functions for reading, calculation and writing are necessary. This problem can be solved without using virtual functions. However, you will receive no credit for it and I will think poorly of you.
Here is a sample input file for this program.
1 23938475683 1111 62000
2 30495848484 2222 40 21.5
3 40394833333 3333 30000
2 48584842283 2232 45 10
2 38485849494 2222 42.5 15
1 34345564433 1111 56000
3 98605050393 3333 12000
3 00033432738 3333 17000
The first value is a code representing the employee type: 1 is salaried, 2 is hourly, and 3 is commission. The next column is the employee ID, the next the department ID of the employee. The next column varies depending on the employee type. For salaried employees it is their salary per annum. For hourly employees it is the number of hours to be paid. Overtime (1.5) is paid for all time over 40 hours. Following the hours in column five is the rate of pay for the employee. For commission employees the fourth column is the amount of sales for the pay period. Commission is paid on a graduated basis: 0 to 15000 earns 12%, greater than 15000 to 25000 earns 15% and greater than 25000 earns 20%. So for $30,000 the pay is 15000 * 12% + 10000 * 15% + 5000 * 20%.
Notice that only hourly employees have five inputs. The others have four. This is easily accomplished using separate functions for each.
Here is a sample output based on the input above.
Employee #23938475683 Dept# 1111 Net pay: $5166.67 Salary:$62000
Employee #30495848484 Dept# 2222 Net pay: $860 Hours:40 Rate:$21.5
Employee #40394833333 Dept# 3333 Net pay: $4300 Sales:$30000
Employee #48584842283 Dept# 2232 Net pay: $475 Hours:45 Rate:$10
Employee #38485849494 Dept# 2222 Net pay: $656.25 Hours:42.5 Rate:$15
Employee #34345564433 Dept# 1111 Net pay: $4666.67 Salary:$56000
Employee #98605050393 Dept# 3333 Net pay: $1440 Sales:$12000
Employee #00033432738 Dept# 3333 Net pay: $2100 Sales:$17000
======================= my solution =========================================
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
class Employee {
public:
char outRecord[120];
char EmpID[12];
char DeptID[5];
double NetPay;
virtual void readWageInfoFromFile(ifstream&, ofstream&)=0;
};
class Salaried : public Employee {
public:
double yearlySalary;
void readWageInfoFromFile(ifstream& inFile, ofstream& outFile)
{
inFile >> EmpID >> DeptID >> yearlySalary;
cout << "just read Salaried \t" << EmpID << DeptID << yearlySalary;
NetPay = .833333333*yearlySalary;
sprintf(outRecord, "Employee #%s Dept #%s NetPay: %9.2f yearlySalary: %9.2f \n",
EmpID, DeptID, NetPay, yearlySalary);
cout << outRecord;
outFile << outRecord;
}
};
class Hourly : public Employee {
public:
double Hours, HourlyRate;
void readWageInfoFromFile(ifstream& inFile, ofstream& outFile)
{
inFile >> EmpID >> DeptID >> Hours >> HourlyRate;
cout << "just read Hourly \t" << EmpID << DeptID << Hours << HourlyRate;
NetPay = Hours*HourlyRate + max(0.0,Hours-40.0)*0.5*HourlyRate;
sprintf(outRecord, "Employee #%s Dept #%s NetPay: %9.2f HourlyRate: %9.2f Hours: %4.1f \n",
EmpID, DeptID, NetPay, HourlyRate, Hours);
cout << outRecord;
outFile << outRecord;
}
};
class Commissioned : public Employee {
public:
double Commission;
double netFromCommission(double Sales){
double netFromCom = 0;
if (Sales <= 15000.0 && Sales >= 0.0) {
netFromCom = .12*Sales;}
else if (Sales <= 25000.0) {
netFromCom = .12*15000.0 + .15*(Sales-15000.0);}
else if (Sales > 25000.0) {
netFromCom = .12*15000.0 + .15*10000.0 + .20*(Sales-25000.0);}
else
cout << "Invalid Sales: " << Sales;
return netFromCom;
}
void readWageInfoFromFile(ifstream& inFile, ofstream& outFile)
{
inFile >> EmpID >> DeptID >> Commission;
cout << "just read Commissioned \t" << EmpID << DeptID << Commission;
NetPay = netFromCommission(Commission);
sprintf(outRecord, "Employee #%s Dept #%s NetPay: %9.2f Sales: %9.2f \n",
EmpID, DeptID, NetPay, Commission);
cout << outRecord;
outFile << outRecord;
}
};
Employee* employeeFactory(int type) {
if (type==1) return new Salaried;
if (type==2) return new Hourly;
if (type==3) return new Commissioned;
}
int main()
{
Employee* empPtr;
int type;
ofstream outFile("OneOutput.txt"); // output, normal file
if(!outFile) {
cout << "Cannot open outfile: OneOutput.txt \n";
return 1;
}
ifstream inFile("OneInput.txt"); // input
if(!inFile) {
cout << "Cannot open input file: 'OneInput.txt' " << endl;
return 1;
}
inFile >> type; //must read at least once before checking eof()
while (!inFile.eof( )) //if not at end of file, continue...
{
//inFile.getline(lineread, 10); // Read line by
if (type!=1 && type!=2 && type!=3) {
cout << "Invalid employee type: " << type;
return(1); }
empPtr = employeeFactory(type);
empPtr->readWageInfoFromFile(inFile, outFile);
inFile >> type;
}
inFile.close();
outFile.close();
return 0;
}
|
============================= my output ===================================
Employee #23938475683 Dept #1111 NetPay: 51666.67 yearlySalary: 62000.00
Employee #30495848484 Dept #2222 NetPay: 860.00 HourlyRate: 21.50 Hours: 40.0
Employee #40394833333 Dept #3333 NetPay: 4300.00 Sales: 30000.00
Employee #48584842283 Dept #2232 NetPay: 475.00 HourlyRate: 10.00 Hours: 45.0
Employee #38485849494 Dept #2222 NetPay: 656.25 HourlyRate: 15.00 Hours: 42.5
Employee #34345564433 Dept #1111 NetPay: 46666.67 yearlySalary: 56000.00
Employee #98605050393 Dept #3333 NetPay: 1440.00 Sales: 12000.00
Employee #00033432738 Dept #3333 NetPay: 2100.00 Sales: 17000.00