Pointer to Class Array Objects

My program is erroring out when I try to add a second set of values to the Hourly class. When I switch to using hours[current_hourly].etc it works fine so I assume it is because of how I'm using pointer hour1. What is the proper way to use the pointer to add values to the properties? Thank you.

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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#include <iostream>
#include <iomanip>
using namespace std;

class Employee
{
protected:
    string empId;
    float hours;
    float pay;
    float incomeTax;
    float overtime;
    string empStatus;
public:
    Employee()
    {
        empStatus = "N/A";
        hours = pay = incomeTax = overtime = 0.0;
        empStatus = "N/A";
    }
    virtual void calculatePay() = 0;
};

class Hourly : public Employee
{
protected:
    float regPay;// = (hours * pay);
    float overPay;// = (overtime * pay * 1.5);
    float grossPay;// = (regPay + overPay);
    float taxes;// = (grossPay * incomeTax);
    float netPay;// = (grossPay - taxes);
public:
    Hourly()
    {
        regPay = overPay = grossPay = taxes = netPay = 0;
    }
    void Overtime()
    {
        if( hours <= 40 )
        {
            overtime = 0;
        }
        else
        {
            overtime = (hours - 40);
            hours = 40;
        }
    }
    void calculatePay()
    {
        Overtime();

        this->regPay = (hours * pay);
        this->overPay = (overtime * pay * 1.5);
        this->grossPay = (regPay + overPay);
        this->taxes = (grossPay * incomeTax);
        this->netPay = (grossPay - taxes);

        //cout << setprecision(2);
        cout << endl << "Employee #" << empId << " has " << hours << " normal hours.\n";
        if( overtime > 0 )
        {
            cout << "Employee #" << empId << " has " << overtime << " overtime hours.\n";
        }
        cout << empId << " is being paid at a rate of $" << pay << " per hour.\n";
        cout << empId << " has $" << regPay << " in pay for normal hours worked.\n";
        if( overPay > 0 )
        {
            cout << empId << " has $" << overPay << " in pay for overtime hours worked.\n";
        }

        cout << "Employee #" << empId << " has a Gross Pay of: $" << grossPay << endl;
        cout << "The taxes withheld amount to $" << taxes << endl;
        cout << "The total amount of money earned is $" << netPay << endl;
    }
};

class Salaried : public Employee
{
private:
    float grossPay;
    float taxWith;
    float netPay;
public:
    void calculatePay()
    {
        //cout << setprecision(2);
        this->grossPay = pay * 40 * 52; // annual salary - 40 hours per week 52 weeks per year
        this->taxWith = (grossPay * incomeTax);
        this->netPay = (grossPay - taxWith);
        cout << endl << "Employee #" << empId << " has a Gross Pay of: $" << grossPay << endl;
        cout << "The taxes withheld amount to: $" << taxWith << endl;
        cout << "The total amount of money earned is: $" << netPay << endl;
    }
};

class Contractor : public Employee
{
private:
    float grossPay;// = pay;   // Seems off.. Fix later
public:
    void calculatePay()
    {
        //cout << fixed << setprecision(5);
        this->grossPay = pay;
        cout << endl << "Employee #" << empId << " has a Gross Pay of: $" << grossPay << endl;
        cout << "The taxes withheld amount to: $0.00" << endl;
        cout << "The total amount of money earned is: $" << grossPay << endl;
    }
};

int main()
{
    char again = 'y';
    int option;
    int current_hourly , current_salaried, current_contracted;
    current_contracted = current_hourly = current_salaried = 0;

    string temp_id, temp_status;
    float temp_hours, temp_pay, temp_tax;

    const int MAX = 10;
    Hourly hours[MAX];
    Salaried salaries[MAX];
    Contractor contractors[MAX];

    Employee *hour1 = &hours[0];
    Employee *salary1 = &salaries[0];
    Employee *contract1 = &contractors[0];

    int hourTotal, salaryTotal, contractTotal;
    hourTotal = salaryTotal = contractTotal = 0;

    while(tolower(again) == 'y')
    {
        cout << "\n1 - Enter Hourly Employee\n";
        cout << "2 - Enter Salaried Employee\n";
        cout << "3 - Enter Contracted Employee\n";
        cout << "4 - Display Hourly Employee\n";
        cout << "5 - Display Salaried Employee\n";
        cout << "6 - Display Contracted Employee\n";
        cout << "7 - Quit\n";
        cout << "\nEnter an option(1-7): ";
        cin >> option;

        switch(option)
        {
            case 1: // Enter Hourly
            {
                if(current_hourly >= MAX-1)
                {
                    cout << "\nError! Maximum amount of Hourly Employees stored.\n";
                    break;
                }
                //hours[current_hourly].SetStatus("Hourly");
                cout << "\nEnter Employee ID: ";
                cin.clear();
                cin.sync();
                getline(cin, temp_id);
                hour1[current_hourly].SetID( temp_id );
                cout << "Enter Total Hours Worked: ";
                cin >> temp_hours;
                hour1[current_hourly].SetHours( temp_hours );
                cout << "Enter Pay Rate: ";
                cin >> temp_pay;
                hour1[current_hourly].SetPay( temp_pay );
                cout << "Enter Income Tax Rate: ";
                cin >> temp_tax;
                hour1[current_hourly].SetTaxRate( temp_tax );
                current_hourly++;
                break;
            }
            case 2: // Enter Salaried
            {
                if(current_salaried >= MAX-1)
                {
                    cout << "\nError! Maximum amount of Salaried Employees stored.\n";
                    break;
                }
                salary1[current_salaried].SetStatus("Salaried");
                cout << "\nEnter Employee ID: ";
                getline(cin, temp_id, '\n');
                salary1[current_salaried].SetID( temp_id );
                cout << "Enter Pay Rate: ";
                cin >> temp_pay;
                salary1[current_salaried].SetPay( temp_pay );
                cout << "Enter Income Tax Rate: ";
                cin >> temp_tax;
                salary1[current_salaried].SetTaxRate( temp_tax );
                current_salaried++;
                break;
            }
            case 3: // Enter Contracted
            {
                if(current_contracted >= MAX-1)
                {
                    cout << "\nError! Maximum amount of Contracted Employees stored.\n";
                    break;
                }
                contract1[current_contracted].SetStatus("Contracted");
                cout << "\nEnter Employee ID: ";
                getline(cin, temp_id, '\n');
                contract1[current_contracted].SetID( temp_id );
                cout << "Enter Pay Rate: ";
                cin >> temp_pay;
                contract1[current_contracted].SetPay( temp_pay );
                current_contracted++;
                break;
            }
            case 4: // Display Hourly
            {
                if( current_hourly < 1 )
                {
                    cout << "\nNo Hourly Employees stored in the database.\n\n";
                    break;
                }
                for( int i = 0; i < current_hourly; i++ )
                {
                    hours[i].calculatePay();
                }
                break;
            }
            case 5: // Display Salaried
            {
                if( current_salaried < 1 )
                {
                    cout << "\nNo Salaried Employees stored in the database.\n\n";
                    break;
                }
                for(int i = 0;i < current_salaried; i++)
                {
                    salary1[i].calculatePay();
                }
                break;
            }
            case 6: // Display Contracted
            {
                if( current_contracted < 1 )
                {
                    cout << "\nNo Contracted Employees stored in the database.\n\n";
                    break;
                }
                for(int i = 0;i < current_contracted; i++)
                {
                    contract1[i].calculatePay();
                }
                break;
            }
            default: // Quit
            {
                cout << "Quitting..\n";
                again = 'n';
                break;
            }
        }
    }

    return 0;
}
Hi,

If you want to do polymorphism, then the base class has to have all the pure virtual function you want to call from the derived classes. You don't seem to have any Set* functions at all, anywhere.

The override keyword is good practise.

It's not a good idea to have protected member variables. Make them private and set them via the base class constructor. Call the base class constructor from the derived classes constructors.

Also prefer double rather than float.

Prefer std::vector rather than arrays.

You could have more functions - for example each case in the switch should call a function. As should displaying the menu.

Good Luck !!
Hello JTwist32,

In addition to what TheIdeasMan said if you have not caught it yet you are missing #include <string> at the top of your program.

After adding the setter and a getter function to the Employee class case 1 started to come together. At first "hours1" did not work so I tried "hours" and that worked.

I figured there is a problem with:

1
2
3
Employee *hour1 = &hours[0];
Employee *salary1 = &salaries[0];
Employee *contract1 = &contractors[0];


The pointer of type "Employee" being set to an address of an array of type "Hourly" does not make much sense. When I change to:

1
2
3
Hourly *hour1 = &hours[0];
Salaried *salary1 = &salaries[0];
Contractor *contract1 = &contractors[0];


hour1 worked the way it should.

As TheIdeasMan said:

It's not a good idea to have protected member variables. Make them private and set them via the base class constructor. Call the base class constructor from the derived classes constructors.

In addition to that none of your classes have a constructor which should set the private variables before it is used.

Hope that helps,

Andy
@Handy Andy

The pointer of type "Employee" being set to an address of an array of type "Hourly" does not make much sense.


I guess the OP is trying to do polymorphism there: pointer to derived is a valid pointer to base :+) What is missing is pushing those pointers into 1 container, not to have 3 separate arrays.

@OP
You could get away without any Set functions, do it with the constructors. Set functions are only necessary if the object is being changed after construction. There might not be a need for Get functions either, write a member function to print the data. Although programs are supposed to be more robust when such get interface functions are written. The idea is the interface remains the same, the function itself can be changed to cope with some internal representation change. For example if the employee status was changed to be a class of it's own.

But one should try to avoid blindly writing a get / set function every member variable - they might as well all be public!! Consider having Update functions that change the values for all the members of the class all at once.

Also consider what you public interface should be: What public functions should the user be able to use?
Topic archived. No new replies allowed.