Ok, I never really understood vectors and I have write a program that uses a vector of Employee references to store the company’s payroll. My program will load the payroll by reading a file (employee.dat) that contains one employee’s information per line. Each line of the file will begin with a letter (S for salaried, H for hourly, C for commission, or B for base plus commission.) The fields on the remainder of the line will depend on the first letter of the line and will be separated by spaces. I didn't think you could use a vector of references but here is the code. Also, I need to know how to read it in from a file and to use the appropriate object. Should I use switch statements or else ifs? Remember, its just modifying it.

#include <iostream>
using std::cout;
using std::endl;
using std::fixed;

#include <iomanip>
using std::setprecision;
  
#include <vector>
using std::vector;

// include definitions of classes in Employee hierarchy
#include "Employee.h"
#include "SalariedEmployee.h" 
#include "HourlyEmployee.h"
#include "CommissionEmployee.h"  
#include "BasePlusCommissionEmployee.h" 

int main()
{
   // create derived-class objects
   SalariedEmployee salariedEmployee( 
      "John", "Smith", "111-11-1111", 800 );
   HourlyEmployee hourlyEmployee( 
      "Karen", "Price", "222-22-2222", 16.75, 40 );
   CommissionEmployee commissionEmployee( 
      "Sue", "Jones", "333-33-3333", 10000, .06 );
   BasePlusCommissionEmployee basePlusCommissionEmployee( 
      "Bob", "Lewis", "444-44-4444", 5000, .04, 300 );

   // create vector of four base-class pointers
   vector < Employee * > employees( 4 );

   // initialize vector with Employees
   employees[ 0 ] = &salariedEmployee;
   employees[ 1 ] = &hourlyEmployee;
   employees[ 2 ] = &commissionEmployee;
   employees[ 3 ] = &basePlusCommissionEmployee;

   return 0;
} // end main

These are all in there own header file associated with there name.

Employee( const string &, const string &, const string & );

//constructor definition
Employee::Employee( const string &first, const string &last,
   const string &ssn )
   : firstName( first ), lastName( last ), socialSecurityNumber( ssn )
{
   // empty body 
} // end Employee constructor
HourlyEmployee( const string &, const string &, 
      const string &, double = 0.0, double = 0.0 );

// constructor definition
HourlyEmployee::HourlyEmployee( const string &first, const string &last, 
   const string &ssn, double hourlyWage, double hoursWorked )
   : Employee( first, last, ssn )   
{
   setWage( hourlyWage ); // validate hourly wage
   setHours( hoursWorked ); // validate hours worked
} // end HourlyEmployee constructor
SalariedEmployee( const string &, const string &, 
      const string &, double = 0.0 );

// constructor definition
SalariedEmployee::SalariedEmployee( const string &first, 
   const string &last, const string &ssn, double salary )
   : Employee( first, last, ssn )
{ 
   setWeeklySalary( salary ); 
} // end SalariedEmployee constructor
CommissionEmployee( const string &, const string &,
      const string &, double = 0.0, double = 0.0 );

// constructor defintion
CommissionEmployee::CommissionEmployee( const string &first, 
   const string &last, const string &ssn, double sales, double rate )
   : Employee( first, last, ssn )  
{
   setGrossSales( sales );
   setCommissionRate( rate );
} // end CommissionEmployee constructor
BasePlusCommissionEmployee( const string &, const string &,
      const string &, double = 0.0, double = 0.0, double = 0.0 );

//constructor definition
BasePlusCommissionEmployee::BasePlusCommissionEmployee( 
   const string &first, const string &last, const string &ssn, 
   double sales, double rate, double salary )
   : CommissionEmployee( first, last, ssn, sales, rate )  
{
   setBaseSalary( salary ); // validate and store base salary
} // end BasePlusCommissionEmployee constructor

Recommended Answers

All 9 Replies

Is your Instructor's name Ron, by chance?

-Alex

I'm guessing this guy was a bad instructor perhaps? No, my instructor isn't Ron, his name is Terry and he was a Software Engineer for 27 years.

1. You can't declare a vector of references in C++ (it's the other story why). Fortunately, I see a vector of POINTERS in you snippet. Feel the difference ;)
2. Why pointers in that case? Better define std::vector<SalariedEmployee> . Take on trust: it's much more better for you ;)
3. What's a problem? Read a file with getline(ifstream,string) line by line, check up the 1st char (with switch or if, it's a matter of taste), then attach the line to istringstream and extract field by field to SalariedEmployee object members then push_back result into the vector. That's all...

I'm guessing this guy was a bad instructor perhaps? No, my instructor isn't Ron, his name is Terry and he was a Software Engineer for 27 years.

By no means am I attempting to discredit any Instructor. The assignment is familiar to me - very similar to what I had to do in a C++ class.

-Alex

1. You can't declare a vector of references in C++ (it's the other story why). Fortunately, I see a vector of POINTERS in you snippet. Feel the difference ;)

Yeah I feel the difference lol.

2. Why pointers in that case? Better define std::vector<SalariedEmployee> . Take on trust: it's much more better for you ;)

I have to use Employee because it is the base class, so I can just use Employee instead of SalariedEmployee? Also, I didn't mention this but after my program has read in the file, it should go into a “query” mode. In this mode, it should prompt for a social security number to be located and the current month (as an integer). It should then search for a match of the SS number and retrieve the current earnings. In addition, if the employee’s birth month matches the current month, I will add a $100 birthday bonus to the earnings. Then I will display the employee’s name, birthdate, and earnings including any bonus. So I need to use pointers still correct?

3. What's a problem? Read a file with getline(ifstream,string) line by line, check up the 1st char (with switch or if, it's a matter of taste), then attach the line to istringstream and extract field by field to SalariedEmployee object members then push_back result into the vector. That's all...

Will this be different now that I've explained what I have to do after I read the file?

Oh yes, I did not pay attention to (potential) polymorphism in your code. Yes, you need a vector of pointers to a base class.
The only difference: create a proper derived class object by operator new and assign the obtained pointer to a base class pointer variable then push_back this value into the vector (and don't forget to traverse the vector and delete all objects before exit).
Yet another tip: if you want to search objects by unique SS numbers, consider std::map<SS_number_type,Employee*> container instead std::vector. You will get a very fast (and free of charge) std::map search by map::find member function.

Ok, so here is what I did so far. Like I said I'm not used to vectors so its pretty new to me. When you said for me to create using new do you mean like this?

salariedEmployee = new Employee;
salariedEmployee = new SalariedEmployee;

As for the push_back command, I'm not sure how to use that. Here is my code. Do I create the new objects inside each case? If your wondering what the input will look like from the file it will be as follows.
S firstName lastName socialSecurityNumber weeklySalary birthdate
H firstName lastName socialSecurityNumber wage hours birthdate
C firstName lastName socialSecurityNumber grossSales commissionRate birthdate
B firstName lastName socialSecurityNumber grossSales commissionRate baseSalary birthdate

S Tom Smith 111-11-1111 800 09/10/1942
H Karen Price 222-22-2222 16.75 40 01/01/1982
C Sue Jones 333-33-3333 10000 .06 05/31/1980
B Bob Lewis 444-44-4444 5000 .04 300 10/04/1950

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <fstream>

// include definitions of classes in Employee hierarchy
#include "Date.h"
#include "Employee.h"
#include "SalariedEmployee.h" 
#include "HourlyEmployee.h"
#include "CommissionEmployee.h"  
#include "BasePlusCommissionEmployee.h" 
using namespace std;

int main()
{
   vector < Employee * > employees;
   string firstName;
   string lastName;
   string ssn;
   double salary;
   double hourlyWage;
   double hoursWorked;
   double sales;
   double rate;
   int    month;
   int    day;
   int    year;
   char   type;   
   fstream indata;                          // The file to be opened

   indata.open("employee.txt"); // Open the file to be read
   if(!indata) 
   { 
      cout << "Error: file could not be opened" << endl;
      exit(1);
   }

   do
   {
      indata>>type;
      switch(type)
      {
         case 'S':
            indata >> firstName;
            indata >> lastName;
            indata >> ssn;
            indata >> salary;
            indata >> month;
            indata.ignore(1);
            indata >> day;
            indata.ignore(1);
            indata >> year;
            break;
         case 'H':
            indata >> firstName;
            indata >> lastName;
            indata >> ssn;
            indata >> hourlyWage;
            indata >> hoursWorked;
            indata >> month;
            indata.ignore(1);
            indata >> day;
            indata.ignore(1);
            indata >> year;
            break;
         case 'C':
            indata >> firstName;
            indata >> lastName;
            indata >> ssn;
            indata >> sales;
            indata >> rate;
            indata >> month;
            indata.ignore(1);
            indata >> day;
            indata.ignore(1);
            indata >> year;
            break;
         case 'B':
            indata >> firstName;
            indata >> lastName;
            indata >> ssn;
            indata >> sales;
            indata >> rate;
            indata >> salary;
            indata >> month;
            indata.ignore(1);
            indata >> day;
            indata.ignore(1);
            indata >> year;
            break;
      }
   }while(!indata.eof());

   return 0;
}

what he meant was
base* b = new child();

then push_back(b) into the vector.

however for dynamic polymorphism you should keep functions which need to be derived from base class as virtual, so that when you call them with the base class pointer it calls the correct child class function.

so basically you need to read about polymorphism and 'dynamic' polymorphism in particular.

Nope, that's wrong approach. Right code sceleton looks like:

Employee* p;
string line;
istringstream sstr;
char key;
bool goon = true;
...
while (goon && getline(indata,line)) {
    sstr.str(line);   // attach new line to sstr
    sstr.seekg(0); // read sstr from the beginning
    sstr >> key;
    switch (key) {
    case 'S':
        ... // get S... fields from sstr
        p = new salariedEmployee(...);
        v.push_back(p);
        break;
    ...
    default: // bad key
        goon = false; // then print error message
        break;
    }
}

But at first let's know about you employees zoo (see Agni's post).
What did you want to do with all these classes? What's base class definition?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.