imlearning
asked on
Casting from derived class
I have a base Employee class and three derived class , Salary, Hourly, and PieceWork
I have a container class
class Employees{
private:
Employee *all[MAX];
int EmployeeCount;
void qs_lname(int left, int right);
public:
Employees():EmployeeCount( 0){}
void add(Employee &e);
void remove(Employee &e);
int search(char* l);
void quickSort(){qs_lname(0,Emp loyeeCount -1);}
void calcAllGross(void);
void calcAllNet(void);
void printByGroups(void);
};
so im working on printByGroups which prints a report grouped by the derived types
and I need to do this
subTotalHours=all[0]->getH ours(); // but getHours is a member of the derived Hourly class
error C2039: 'getHours' : is not a member of 'Employee'
how do I cast so that i can get to that method
I have a container class
class Employees{
private:
Employee *all[MAX];
int EmployeeCount;
void qs_lname(int left, int right);
public:
Employees():EmployeeCount(
void add(Employee &e);
void remove(Employee &e);
int search(char* l);
void quickSort(){qs_lname(0,Emp
void calcAllGross(void);
void calcAllNet(void);
void printByGroups(void);
};
so im working on printByGroups which prints a report grouped by the derived types
and I need to do this
subTotalHours=all[0]->getH
error C2039: 'getHours' : is not a member of 'Employee'
how do I cast so that i can get to that method
ASKER
hi jkr
i tried doing just that
float subTotalHours=((Hourly*)al l[0])->get Hours();
and i get
error C2059: syntax error : ')'
syntax error : identifier 'Hourly'
error C2061: syntax error : identifier 'Hourly'
error C2065: 'Hourly' : undeclared identifier
Let me explain how I have my project setup
I have employee.h // Has Employee(base)class and Employees (container) Class
and hourly.h // #include "employee.h"
salary.h// #include "employee.h"
pieceWork.h // #include "employee.h"
and my payroll.cpp (main)
#include "employee.h"
#include "hourly.h"
#include "salary.h"
#include "piecework.h"
is that the problem ? ( im new with header files)
thanks
i tried doing just that
float subTotalHours=((Hourly*)al
and i get
error C2059: syntax error : ')'
syntax error : identifier 'Hourly'
error C2061: syntax error : identifier 'Hourly'
error C2065: 'Hourly' : undeclared identifier
Let me explain how I have my project setup
I have employee.h // Has Employee(base)class and Employees (container) Class
and hourly.h // #include "employee.h"
salary.h// #include "employee.h"
pieceWork.h // #include "employee.h"
and my payroll.cpp (main)
#include "employee.h"
#include "hourly.h"
#include "salary.h"
#include "piecework.h"
is that the problem ? ( im new with header files)
thanks
ASKER
also here is my main
Employee *test = new Hourly("Doe","John",27.00, 46.50,50);
Employee *test2 = new PieceWork("Whittle","Ed",1 1.50,25.50 ,0);
Employee *test3 = new PieceWork("Marion","Louise ",13,40,10 0);
Employee *test4 = new Salary("Prentiss","Paula", 15.75*50.5 ,124);
Employee *test5 = new Hourly("Davidson","Carl",8 .75,38,15) ;
Employees Company;
Company.add(*test);
Company.add(*test2);
Company.add(*test3);
Company.add(*test4);
Company.add(*test5);
Employee *test = new Hourly("Doe","John",27.00,
Employee *test2 = new PieceWork("Whittle","Ed",1
Employee *test3 = new PieceWork("Marion","Louise
Employee *test4 = new Salary("Prentiss","Paula",
Employee *test5 = new Hourly("Davidson","Carl",8
Employees Company;
Company.add(*test);
Company.add(*test2);
Company.add(*test3);
Company.add(*test4);
Company.add(*test5);
No, that should work. It is however hard to diagnose what'S going wrong without seeing more of the code.
You add the function getHours(); in the Employee class.
for example
class Employee
{
..
..
..
public:
int getHours()
{
}
};
for example
class Employee
{
..
..
..
public:
int getHours()
{
}
};
ASKER
heres my code, thanksfor your time jkr
========================== ========== ========== =========
class Employee {
protected:
enum EmployeeType {salaried,hourly,piecework }; // derived types
private:
char *lname;
char *fname;
float deffered;
float gross;
float net;
float fedTax;
float stateTax;
float ssiTax;
float calcFed(void) {return (gross-deffered)*FEDTAXRAT E;}
float calcState(void){return (fedTax * STATETAXRATE);}
float calcSSI(void){return (gross-deffered)*SSITAXRAT E;}
public:
Employee(const char*last="",const char* first="",float deff=0.0)
:lname(NULL), fname(NULL),deffered(deff) ,gross(0), net(0), fedTax(0), stateTax(0), ssiTax(0)
{
int len = strlen(last);
lname = new char[len+1];
strcpy(lname, last);
len = strlen(first);
fname = new char[len+1];
strcpy(fname, first);
}
~Employee()//destruct
{
delete [] fname;
delete [] lname;
}
char* getLastName(void)const{ret urn this->lname;}
char* getFirstName(void)const{re turn fname;}
const float getDeffered(void)const{ret urn deffered;}
const float getGross(void)const{return gross;}
const float getNet(void)const{return net;}
const float getFedTax(void)const{retur n fedTax;}
const float getStateTax(void)const{ret urn stateTax;}
const float getSSITax(void)const{retur n ssiTax;}
void setLastName(const char * last){ int len =strlen(last);lname = new char[len+1];strcpy(lname, last);}
void setFirstName(const char * first){int len =strlen(first);fname = new char[len+1];strcpy(fname, first);}
void setDeffered(const float def){deffered=def;}
void setGross(const float f){gross=f;}
void calcNet(void);
virtual void calcGross(void)=0;
virtual EmployeeType GetType() const = 0;
};
void Employee::calcNet(void)
{
if(this->getGross()>0)
{ // protect the data
this->fedTax = calcFed();
this->stateTax = calcState();
this->ssiTax = calcSSI();
this->net = gross-(fedTax+stateTax+ssi Tax+deffer ed);
}
else
{ cout<<"\nGross is less than Zero";}
}
========================== ========== ========== =====
class Employees{
private:
Employee *all[MAX];
int EmployeeCount;
void qs_lname(int left, int right);
public:
Employees():EmployeeCount( 0){}
void add(Employee &e);
void remove(Employee &e);
int search(char* l);
void quickSort(){qs_lname(0,Emp loyeeCount -1);}
void calcAllGross(void);
void calcAllNet(void);
void printByGroups(void);
};
void Employees::calcAllGross(vo id)
{
for(int i =0;i<EmployeeCount;i++)
all[i]->calcGross();
}
void Employees::qs_lname(int left, int right)
{
int i, j;
const char *x; // temp string
i = left; j = right;
x = all[(left+right)/2]->getLa stName(); // sorting by last name
do
{
while((strcmp(all[i]->getL astName(), x) < 0) && (i < right))i++;
while((strcmp(all[j]->getL astName(), x) > 0) && (j > left)) j--;
if(i <= j)
{ // swap
Employee *temp =all[i];
all[i] = all[j];
all[j] = temp;
i++; j--;
}
} while(i <= j);
if(left < j) qs_lname(left, j);
if(i < right) qs_lname(i, right);
}
void Employees::printByGroups(v oid)
{
float subTotalHours=((Hourly*)al l[0])->get Hours();
}
void Employees:: calcAllNet(void)
{
for(int i =0;i<EmployeeCount;i++)
all[i]->calcNet();
}
void Employees::add(Employee &e)
{
if(EmployeeCount<MAX)
{ int found=search(e.getFirstNam e()); // search first if employee exists
if(found==-1)
{
all[EmployeeCount]=&e;
EmployeeCount++;
return;
}
else
{
cout<<"\nEmployee Already Exist: not added: \n";
return;
}
}
else
cout<<"\n Error :Container Is Full:\n";
}
int Employees::search(char* l)
{
for(int i=0;i<EmployeeCount;i++)
{
if(strcmp(l, all[i]->getLastName())==0)
return i;
}
return-1;
}
void Employees::remove(Employee &e)
{
int found=search(e.getLastName ());
if (found >= 0)
{ Employee *erase=0; // Null Pointer
all[found]=all[EmployeeCou nt-1];//se t found to last pointer
all[EmployeeCount-1]=erase ;//set last pointer to null
--EmployeeCount;
quickSort();
}
}
========================== ========== ==========
class Hourly : public Employee{
private:
float hours;
float payrate;
public:
Hourly(char * last="",char *first="",float pr=0,float hr=0,float deff=0):
hours(hr>0?hr:0),payrate(p r>0?pr:0), Employee(l ast,first, deff){}
Hourly(Hourly &h):
hours(h.getHours()),payrat e(h.getPay Rate()),Em ployee(h.g etLastName (),h.getFi rstName(), h.getDeffe red()){}
void setHours(const float f){(f>0)?hours=f:hours=0;}
float getHours(void)const{return hours;}
void setPayRate(const float f){(f>0)?payrate=f:payrate =0;}
float getPayRate(void)const{retu rn payrate;}
void calcGross()
{
if(hours <= 40)
this->setGross(hours * payrate);
else
this->setGross( 40 * payrate + (hours-40)* 1.5 * payrate);
}
virtual EmployeeType GetType() const { return hourly;}
};
========================== ========== ========== ==
==========================
class Employee {
protected:
enum EmployeeType {salaried,hourly,piecework
private:
char *lname;
char *fname;
float deffered;
float gross;
float net;
float fedTax;
float stateTax;
float ssiTax;
float calcFed(void) {return (gross-deffered)*FEDTAXRAT
float calcState(void){return (fedTax * STATETAXRATE);}
float calcSSI(void){return (gross-deffered)*SSITAXRAT
public:
Employee(const char*last="",const char* first="",float deff=0.0)
:lname(NULL), fname(NULL),deffered(deff)
{
int len = strlen(last);
lname = new char[len+1];
strcpy(lname, last);
len = strlen(first);
fname = new char[len+1];
strcpy(fname, first);
}
~Employee()//destruct
{
delete [] fname;
delete [] lname;
}
char* getLastName(void)const{ret
char* getFirstName(void)const{re
const float getDeffered(void)const{ret
const float getGross(void)const{return
const float getNet(void)const{return net;}
const float getFedTax(void)const{retur
const float getStateTax(void)const{ret
const float getSSITax(void)const{retur
void setLastName(const char * last){ int len =strlen(last);lname = new char[len+1];strcpy(lname, last);}
void setFirstName(const char * first){int len =strlen(first);fname = new char[len+1];strcpy(fname, first);}
void setDeffered(const float def){deffered=def;}
void setGross(const float f){gross=f;}
void calcNet(void);
virtual void calcGross(void)=0;
virtual EmployeeType GetType() const = 0;
};
void Employee::calcNet(void)
{
if(this->getGross()>0)
{ // protect the data
this->fedTax = calcFed();
this->stateTax = calcState();
this->ssiTax = calcSSI();
this->net = gross-(fedTax+stateTax+ssi
}
else
{ cout<<"\nGross is less than Zero";}
}
==========================
class Employees{
private:
Employee *all[MAX];
int EmployeeCount;
void qs_lname(int left, int right);
public:
Employees():EmployeeCount(
void add(Employee &e);
void remove(Employee &e);
int search(char* l);
void quickSort(){qs_lname(0,Emp
void calcAllGross(void);
void calcAllNet(void);
void printByGroups(void);
};
void Employees::calcAllGross(vo
{
for(int i =0;i<EmployeeCount;i++)
all[i]->calcGross();
}
void Employees::qs_lname(int left, int right)
{
int i, j;
const char *x; // temp string
i = left; j = right;
x = all[(left+right)/2]->getLa
do
{
while((strcmp(all[i]->getL
while((strcmp(all[j]->getL
if(i <= j)
{ // swap
Employee *temp =all[i];
all[i] = all[j];
all[j] = temp;
i++; j--;
}
} while(i <= j);
if(left < j) qs_lname(left, j);
if(i < right) qs_lname(i, right);
}
void Employees::printByGroups(v
{
float subTotalHours=((Hourly*)al
}
void Employees:: calcAllNet(void)
{
for(int i =0;i<EmployeeCount;i++)
all[i]->calcNet();
}
void Employees::add(Employee &e)
{
if(EmployeeCount<MAX)
{ int found=search(e.getFirstNam
if(found==-1)
{
all[EmployeeCount]=&e;
EmployeeCount++;
return;
}
else
{
cout<<"\nEmployee Already Exist: not added: \n";
return;
}
}
else
cout<<"\n Error :Container Is Full:\n";
}
int Employees::search(char* l)
{
for(int i=0;i<EmployeeCount;i++)
{
if(strcmp(l, all[i]->getLastName())==0)
return i;
}
return-1;
}
void Employees::remove(Employee
{
int found=search(e.getLastName
if (found >= 0)
{ Employee *erase=0; // Null Pointer
all[found]=all[EmployeeCou
all[EmployeeCount-1]=erase
--EmployeeCount;
quickSort();
}
}
==========================
class Hourly : public Employee{
private:
float hours;
float payrate;
public:
Hourly(char * last="",char *first="",float pr=0,float hr=0,float deff=0):
hours(hr>0?hr:0),payrate(p
Hourly(Hourly &h):
hours(h.getHours()),payrat
void setHours(const float f){(f>0)?hours=f:hours=0;}
float getHours(void)const{return
void setPayRate(const float f){(f>0)?payrate=f:payrate
float getPayRate(void)const{retu
void calcGross()
{
if(hours <= 40)
this->setGross(hours * payrate);
else
this->setGross( 40 * payrate + (hours-40)* 1.5 * payrate);
}
virtual EmployeeType GetType() const { return hourly;}
};
==========================
If you have the pointer of a parent class, then you cannot access the functions of the derived class. If all the derived classes are having getHours function, then declare the function in parent class ie Employee class as i have shown above and implement the function in all the derived classes. the compiler will call the function of the class to which the object is pointing at run time.
The error is because you have Employee class pointer ie test,test2, test3, test4 . when you call test->getHours() compiler cannot resolve the function name because its not defined in the Employee class.
hope this could help you
The error is because you have Employee class pointer ie test,test2, test3, test4 . when you call test->getHours() compiler cannot resolve the function name because its not defined in the Employee class.
hope this could help you
What file is
void Employees::printByGroups(v oid)
{
float subTotalHours=((Hourly*)al l[0])->get Hours();
}
?
You will have to add
#include "hourly.h"
to that one also.
void Employees::printByGroups(v
{
float subTotalHours=((Hourly*)al
}
?
You will have to add
#include "hourly.h"
to that one also.
ASKER
per the assignment spec getHours can't be a member of Employee
I tried adding #include"hourly.h" to "employee.h"
error C2440: 'initializing' : cannot convert from 'Hourly *' to 'Employee *'
error C2440: 'initializing' : cannot convert from 'Hourly *' to 'Employee *'
error C2501: 'Hourly::EmployeeType' : missing storage-class or type specifiers
hourly.h(2): error C2504: 'Employee' : base class undefined
Should I put all the derived classes and base class in one file ?
Or should i change my container data member ?? or is that not the problem ?
thanks guys
I tried adding #include"hourly.h" to "employee.h"
error C2440: 'initializing' : cannot convert from 'Hourly *' to 'Employee *'
error C2440: 'initializing' : cannot convert from 'Hourly *' to 'Employee *'
error C2501: 'Hourly::EmployeeType' : missing storage-class or type specifiers
hourly.h(2): error C2504: 'Employee' : base class undefined
Should I put all the derived classes and base class in one file ?
Or should i change my container data member ?? or is that not the problem ?
thanks guys
ASKER
I also tried putting all the code into one cpp file and i get
test.cpp(139): error C2065: 'Hourly' : undeclared identifier
test.cpp(259): error C2061: syntax error : identifier 'Hourly'
is it because of the way my container is holding the data ?
test.cpp(139): error C2065: 'Hourly' : undeclared identifier
test.cpp(259): error C2061: syntax error : identifier 'Hourly'
is it because of the way my container is holding the data ?
Put the classes/implementation to the following files:
// employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
class Employee
{
...
friend class Employees;
};
#endif
// end of employee.h
// employees.h
#ifndef EMPLOYEES_H
#define EMPLOYEES_H
class Employees
{
...
};
#endif
// end of employees.h
// hourly.h
#ifndef HOURLY_H
#define HOURLY_H
#include "employee.h"
class Hourly : public Employee
{
...
};
#endif
// end of hourly.h
put all your member implementation to according employee.cpp, employees.cpp, hourly.cpp .
All cpp can include all needed header files.
Some remarks to the class design:
if you are not allowed to declare friend classes, you have to provide public get/set functions for class Employee.
Hourly doesn't seem a good derivation of class Employee. A public derivation is a so-called "IS A" relation, i.e. an 'Hourly' *is an* 'Employee' in your case. That hardly is a good design. If I am right that is the reason why you got problems when managing 'Hourly' objects by means of an array of employee pointers. I would say class Employee should 'have' an Hourly object as member - or use a pointer if not all employees have a 'Hourly' extension.
If you post the spec we can give you more advice.
Regards, Alex
// employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
class Employee
{
...
friend class Employees;
};
#endif
// end of employee.h
// employees.h
#ifndef EMPLOYEES_H
#define EMPLOYEES_H
class Employees
{
...
};
#endif
// end of employees.h
// hourly.h
#ifndef HOURLY_H
#define HOURLY_H
#include "employee.h"
class Hourly : public Employee
{
...
};
#endif
// end of hourly.h
put all your member implementation to according employee.cpp, employees.cpp, hourly.cpp .
All cpp can include all needed header files.
Some remarks to the class design:
if you are not allowed to declare friend classes, you have to provide public get/set functions for class Employee.
Hourly doesn't seem a good derivation of class Employee. A public derivation is a so-called "IS A" relation, i.e. an 'Hourly' *is an* 'Employee' in your case. That hardly is a good design. If I am right that is the reason why you got problems when managing 'Hourly' objects by means of an array of employee pointers. I would say class Employee should 'have' an Hourly object as member - or use a pointer if not all employees have a 'Hourly' extension.
If you post the spec we can give you more advice.
Regards, Alex
ASKER
Hi alex,
I dont know if you remember but you helped me build the Employee and Employees class. And now our assignment was to derive three classes(salary,hourly,piec ework) from the Employee class, and make the Employee class abstract by making calcGross a purevirtual service.
So since i had to do this
Employee *test = new Hourly("Doe","John",27.00, 46.50,50);
I had to change my container(Employees class) right ? becuase the old one did this
Employees(void) : allEmployees(NULL), EmployeeCount(0), EmployeeSize(0)
{allEmployees= new Employee[EmployeeSize];}
// and i was getting a compile error saying i cant instance a abstract type
So I changed my container to hold an array of pointers to Employees only,
Employee *all[MAX];<--is it ok that i dont dynamically allocate w/ new
int EmployeeCount;
public:
Employees():EmployeeCount( 0){} <-is it ok that i dont dynamically allocate w/new
Was that the right thing to do ?
I will work on creating the header files in the meantime, it doesnt help that this project is due today(5:30pm pacific time), He only gave us a week to do it, but i thought it would be a cake walk since i got 110% on the last project you helped me with
thanks alex
ps for reference my old ID was dreaminbinay
I dont know if you remember but you helped me build the Employee and Employees class. And now our assignment was to derive three classes(salary,hourly,piec
So since i had to do this
Employee *test = new Hourly("Doe","John",27.00,
I had to change my container(Employees class) right ? becuase the old one did this
Employees(void) : allEmployees(NULL), EmployeeCount(0), EmployeeSize(0)
{allEmployees= new Employee[EmployeeSize];}
// and i was getting a compile error saying i cant instance a abstract type
So I changed my container to hold an array of pointers to Employees only,
Employee *all[MAX];<--is it ok that i dont dynamically allocate w/ new
int EmployeeCount;
public:
Employees():EmployeeCount(
Was that the right thing to do ?
I will work on creating the header files in the meantime, it doesnt help that this project is due today(5:30pm pacific time), He only gave us a week to do it, but i thought it would be a cake walk since i got 110% on the last project you helped me with
thanks alex
ps for reference my old ID was dreaminbinay
>>>> And now our assignment was to derive three classes(salary,hourly,piec ework)
As I told you above, a public derivation is called an "is a" relation. So, hourly, salary, piecework are very poor names for derivations of class employee when looking on them with an OO kind of view... But never mind. The above at least gets some sense...
>>>> So I changed my container to hold an array of pointers to Employees only,
Yes, that is good. You need access the baseclass pointers virtually to get access to the *real* objects.
>>>> is it ok that i dont dynamically allocate w/ new
That depends on your requirements. If you can determine a suitable maximum size of the number of employees, it is ok. If your requirement is to be able to manage a dynamical count of employees you should turn to the Employees class we already made dynamically last time.
>>>> per the assignment spec getHours can't be a member of Employee
That is ok, cause you have three cases of employees, you shouldn't have a virtual function in the baseclass that is only valid for one specialization. The key issue is that you should *drive* the application by iterating the employees array and call the virtual function calcGross. After calling you are in the context of the derived class waht means that in Hourly::calcGross you can call Hourly::getHourly(...) without problems and in Salary::calcGross you can call Salary::getMonthlySalary(. ..), and so on... Do you get the point?
Regards, Alex
As I told you above, a public derivation is called an "is a" relation. So, hourly, salary, piecework are very poor names for derivations of class employee when looking on them with an OO kind of view... But never mind. The above at least gets some sense...
>>>> So I changed my container to hold an array of pointers to Employees only,
Yes, that is good. You need access the baseclass pointers virtually to get access to the *real* objects.
>>>> is it ok that i dont dynamically allocate w/ new
That depends on your requirements. If you can determine a suitable maximum size of the number of employees, it is ok. If your requirement is to be able to manage a dynamical count of employees you should turn to the Employees class we already made dynamically last time.
>>>> per the assignment spec getHours can't be a member of Employee
That is ok, cause you have three cases of employees, you shouldn't have a virtual function in the baseclass that is only valid for one specialization. The key issue is that you should *drive* the application by iterating the employees array and call the virtual function calcGross. After calling you are in the context of the derived class waht means that in Hourly::calcGross you can call Hourly::getHourly(...) without problems and in Salary::calcGross you can call Salary::getMonthlySalary(.
Regards, Alex
ASKER
alex
-- I set up the header files per your spec
--when im calcingGross i do that in the container
void Employees::calcAllGross(vo id)
{
for(int i =0;i<EmployeeCount;i++)
all[i]->calcGross();
}
and that works fine
now im lost again....
per the assignment spec we have to produce a report method in the Employees class that totals and subtotals the derived classes.
so making this method
void Employees::printByGroups(v oid)
{
for(int i=0 ; i<EmployeeCount ; i++)
{
if(all[i]->GetType()==1) //this is a hourly derived type
{ //print employee line to file and subTotals for Hourly go here
float subTotalHours=((Hourly*)al l[0])->get Hours(); <-- trying to cast up
}
}
}
is this the wrong approach ? thanks again for your time
-- I set up the header files per your spec
--when im calcingGross i do that in the container
void Employees::calcAllGross(vo
{
for(int i =0;i<EmployeeCount;i++)
all[i]->calcGross();
}
and that works fine
now im lost again....
per the assignment spec we have to produce a report method in the Employees class that totals and subtotals the derived classes.
so making this method
void Employees::printByGroups(v
{
for(int i=0 ; i<EmployeeCount ; i++)
{
if(all[i]->GetType()==1) //this is a hourly derived type
{ //print employee line to file and subTotals for Hourly go here
float subTotalHours=((Hourly*)al
}
}
}
is this the wrong approach ? thanks again for your time
>>>> if(all[i]->GetType()==1)
That is bad. Or let us say it is against virtuality that the baseclass or its container do know about all types (so I must admit that most report writers know about the kind of objects supposed to get printed).
To make it really good, you should sort the container on the type attribute. I think a bubble sort would do like
void Employees::sortTypes()
{
for(int i=0 ; i<EmployeeCount ; i++)
for(int j=i+1 ; j<EmployeeCount ; j++)
{
if(all[j]->GetType() < all[s]->GetType() ) //this is a hourly derived type
{
Employee* pTemp = all[i];
all[i] = all[j];
all[j] = pTemp;
}
}
}
After doing so, the container was separated into groups.
You now can iterate again and if type changes you call a virtuelly defined 'printTotal' function to close the previous group (of course only if it isn't the very first group). The printTotal would print static defined members of the derived class which represent the total of all 'gross' values for that class. You have to fill these values in calcGross function. Then call 'printTitle' virtually what would print the title line(s) for the next group. For each element of that group call virtually 'printGros' which prints the statistics for one element of the container. Finally, call 'printTotal' for the last group (outside of the loop.)
void Employees::printReport()
{
// check (EmployeeCount > 0)
...
// sort employees into groups
...
// init last type to an unknown type, e. g. -1
...
// iterate the sorted container
for( ...
{
// check if type changed
...
{
// call PrintTotal for the previous element (if exist)
...
// call PrintTitle for the current element
...
// save last type to current type
...
}
// call PrintGross for the current element
}
// call PrintTotal for the last element in the container
...
}
Hope, it was understandable.
Regards, Alex
That is bad. Or let us say it is against virtuality that the baseclass or its container do know about all types (so I must admit that most report writers know about the kind of objects supposed to get printed).
To make it really good, you should sort the container on the type attribute. I think a bubble sort would do like
void Employees::sortTypes()
{
for(int i=0 ; i<EmployeeCount ; i++)
for(int j=i+1 ; j<EmployeeCount ; j++)
{
if(all[j]->GetType() < all[s]->GetType() ) //this is a hourly derived type
{
Employee* pTemp = all[i];
all[i] = all[j];
all[j] = pTemp;
}
}
}
After doing so, the container was separated into groups.
You now can iterate again and if type changes you call a virtuelly defined 'printTotal' function to close the previous group (of course only if it isn't the very first group). The printTotal would print static defined members of the derived class which represent the total of all 'gross' values for that class. You have to fill these values in calcGross function. Then call 'printTitle' virtually what would print the title line(s) for the next group. For each element of that group call virtually 'printGros' which prints the statistics for one element of the container. Finally, call 'printTotal' for the last group (outside of the loop.)
void Employees::printReport()
{
// check (EmployeeCount > 0)
...
// sort employees into groups
...
// init last type to an unknown type, e. g. -1
...
// iterate the sorted container
for( ...
{
// check if type changed
...
{
// call PrintTotal for the previous element (if exist)
...
// call PrintTitle for the current element
...
// save last type to current type
...
}
// call PrintGross for the current element
}
// call PrintTotal for the last element in the container
...
}
Hope, it was understandable.
Regards, Alex
ASKER
Alex I understand the sortType
so here is what my driver is doing
Employee *test = new Hourly("Doe","John",27.00, 46.50,50);
Employee *test2 = new PieceWork("Whittle","Ed",1 1.50,25.50 ,0);
Employee *test3 = new PieceWork("Marion","Louise ",13,40,10 0);
Employee *test4 = new Salary("Prentiss","Paula", 15.75*50.5 ,124);
Employee *test5 = new Hourly("Davidson","Carl",8 .75,38,15) ;
Employees Company;
Company.add(*test);
Company.add(*test2);
Company.add(*test3);
Company.add(*test4);
Company.add(*test5);
Company.calcAllGross();
Company.calcAllNet();
Company.sortTypes();
so now all of my pointers are sorted by types
now for the Employees::printReport()
my Report headers are this
Employee Pay Reg Hrs Gross Fed SSI Net
Name Rate Ovt Hrs Pay State Defr Pay
======= ====== ====== ====== ====== ====== =====
and per assignment spec I need
1.) Each derived types to be grouped, and sorted by last name, and have subtotals for each group i.e subtotal all Hourly Employees payRate, regHours,OvtHours ....
so im going to change the sortType to include sorting by last name
now when i get to here im not understanding the logic
void Employees::printReport()
{
if (EmployeeCount > 0)
...
this.sorthType();
...
// init last type to an unknown type, e. g. -1 <--- confused??
...
for( ...
{
// check if type changed <--- how do i do this??
...
{
// call PrintTotal for the previous element (if exist) <-- what is printTotal ?
...
// call PrintTitle for the current element
...
// save last type to current type
...
}
// call PrintGross for the current element
}
// call PrintTotal for the last element in the container
...
}
thanks alex
so here is what my driver is doing
Employee *test = new Hourly("Doe","John",27.00,
Employee *test2 = new PieceWork("Whittle","Ed",1
Employee *test3 = new PieceWork("Marion","Louise
Employee *test4 = new Salary("Prentiss","Paula",
Employee *test5 = new Hourly("Davidson","Carl",8
Employees Company;
Company.add(*test);
Company.add(*test2);
Company.add(*test3);
Company.add(*test4);
Company.add(*test5);
Company.calcAllGross();
Company.calcAllNet();
Company.sortTypes();
so now all of my pointers are sorted by types
now for the Employees::printReport()
my Report headers are this
Employee Pay Reg Hrs Gross Fed SSI Net
Name Rate Ovt Hrs Pay State Defr Pay
======= ====== ====== ====== ====== ====== =====
and per assignment spec I need
1.) Each derived types to be grouped, and sorted by last name, and have subtotals for each group i.e subtotal all Hourly Employees payRate, regHours,OvtHours ....
so im going to change the sortType to include sorting by last name
now when i get to here im not understanding the logic
void Employees::printReport()
{
if (EmployeeCount > 0)
...
this.sorthType();
...
// init last type to an unknown type, e. g. -1 <--- confused??
...
for( ...
{
// check if type changed <--- how do i do this??
...
{
// call PrintTotal for the previous element (if exist) <-- what is printTotal ?
...
// call PrintTitle for the current element
...
// save last type to current type
...
}
// call PrintGross for the current element
}
// call PrintTotal for the last element in the container
...
}
thanks alex
ASKER
also alex can you take a look at my add
void Employees::add(Employee &e)
{
if(EmployeeCount<MAX)
{ int found=search(e.getFirstNam e()); // search first if employee exists
if(found==-1)
{
all[EmployeeCount]=&e; <<----- is this ok ????
EmployeeCount++;
return;
}
else
{
cout<<"\nEmployee Already Exist: not added: \n";
return;
}
}
else
cout<<"\n Error :Container Is Full:\n";
}
void Employees::add(Employee &e)
{
if(EmployeeCount<MAX)
{ int found=search(e.getFirstNam
if(found==-1)
{
all[EmployeeCount]=&e; <<----- is this ok ????
EmployeeCount++;
return;
}
else
{
cout<<"\nEmployee Already Exist: not added: \n";
return;
}
}
else
cout<<"\n Error :Container Is Full:\n";
}
>>>> so im going to change the sortType to include sorting by last name
Change the sorting condition to
if(all[j]->GetType() < all[i]->GetType() ||
(all[j]->GetType() == all[i]->GetType() && all[j]->GetName() < all[i]->GetName() ) )
// init last type to an unknown type, e. g. -1 <--- confused??
e. g.
// employee.h
enum { no_type = -1, hourly, salary, piecework };
// employees.cpp
...
int lasttype = no_type; // that is done to get the title of the first group printed
>>>> // check if type changed <--- how do i do this??
Exactly, that is the corresponding part to the above:
if (all[i]->getType() != lasttype)
{
all[i]->PrintTitle(); // pints the title of any new group including the very first
...
>>>> <-- what is printTotal ?
You are right it should be called PrintSubTotal. It is the sum line (the total for Gross Pay and Net Pay) for one group.
Regards, Alex
Change the sorting condition to
if(all[j]->GetType() < all[i]->GetType() ||
(all[j]->GetType() == all[i]->GetType() && all[j]->GetName() < all[i]->GetName() ) )
// init last type to an unknown type, e. g. -1 <--- confused??
e. g.
// employee.h
enum { no_type = -1, hourly, salary, piecework };
// employees.cpp
...
int lasttype = no_type; // that is done to get the title of the first group printed
>>>> // check if type changed <--- how do i do this??
Exactly, that is the corresponding part to the above:
if (all[i]->getType() != lasttype)
{
all[i]->PrintTitle(); // pints the title of any new group including the very first
...
>>>> <-- what is printTotal ?
You are right it should be called PrintSubTotal. It is the sum line (the total for Gross Pay and Net Pay) for one group.
Regards, Alex
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hey thanks alot alex ..
i got everything .. alot to take in for a newbie , but as i have said before you have taught me more in one of these post than ive learned all semester.
thanks again for your time and detailed posts
i got everything .. alot to take in for a newbie , but as i have said before you have taught me more in one of these post than ive learned all semester.
thanks again for your time and detailed posts
subTotalHours=((Hourly*)al