Should this have a destructor, and should I free dynamically allocated memory? Any suggestions?

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
260
261
262
263
264
265
266
267
// Assign dynamically allocated derived class objects to base class pointers
// and use polymorphism to display output based on the type of the object.

#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

// base class Employee
class Employee
{
private:
	// employee ID
	int empID;

public:
	// Constructor that will take an int as an argument and
	// assign it to empID
	Employee(int);

	// Destructor
	~Employee();

	// Return the empID
	int getEmpID() const;

	// pure virtual function
	virtual void printPay() = 0;

};
// Constructor that will take an int as an argument and
// assign it to empID
Employee::Employee(int empID)
{
	this->empID = empID;
}

// Destructor
Employee::~Employee()
{
}

// Return the empID
int Employee::getEmpID() const
{
	return empID;
}

// derived class HourlyEmployee
class HourlyEmployee : public Employee
{
public:
	// Constructor that will take in three arguments: The employee
	// id, the number of hours worked, and the pay rate.
	HourlyEmployee(int, double, double);

	// Destructor
	~HourlyEmployee();

	// Return the hours
	double getHours() const;

	// Return the payRate
	double getPayRate() const;

	// Print the hourly employee's id and the weekly pay with 2 digits
	// after the decimal place.
	void printPay();

private:
	// number of hours worked
	double hours;
	// pay rate
	double payRate;
};

// Constructor that will take in three arguments: The employee
// id, the number of hours worked, and the pay rate.
HourlyEmployee::HourlyEmployee(int empID, double hours, double payRate) 
	: Employee(empID)
{
	this->hours = hours;
	this->payRate = payRate;
}

// Destructor
HourlyEmployee::~HourlyEmployee()
{
}


// Return the hours
double HourlyEmployee::getHours() const
{
	return hours;
}

// Return the payRate
double HourlyEmployee::getPayRate() const
{
	return payRate;
}

// Print the hourly employee's id and the weekly pay with 2 digits
// after the decimal place.
void HourlyEmployee::printPay()
{
	// calculate weekly pay
	double weeklyPay = hours * payRate;

	// set floating point output to 2 digits after the decimal place
	cout << fixed << showpoint << setprecision(2);

	cout << "The pay for the hourly employee with ID number ";
	cout << getEmpID() << " is  $" << weeklyPay << endl;
}

// derived class SalariedEmployee
class SalariedEmployee : public Employee
{
public:
	// Constructor that will take in two arguments: The employee id and
	// the salary.
	SalariedEmployee(int, double);

	// Destructor
	~SalariedEmployee();

	// Return the salary
	double getSalary() const;

	// Print the salaried employee's id number and the weekly pay with
	// 2 digits after the decimal place.
	void printPay();

private:
	// salary
	double salary;
};

// Constructor that will take in two arguments: The employee id and
// the salary.
SalariedEmployee::SalariedEmployee(int empID, double salary) : Employee(empID)
{
	this->salary = salary;
}

// Destructor
SalariedEmployee::~SalariedEmployee()
{
}

// Return the salary
double SalariedEmployee::getSalary() const
{
	return salary;
}

// Print the salaried employee's id number and the weekly pay with
// 2 digits after the decimal place.
void SalariedEmployee::printPay()
{
	// calculate the weekly pay
	double weeklyPay = salary / 52;

	// set floating point output to 2 digits after the decimal place
	cout << fixed << showpoint << setprecision(2);

	cout << "The pay for the salaried employee with ID number ";
	cout << getEmpID() << " is  $" << weeklyPay << endl;
}

// function prototypes
void getInput(vector <Employee *> & Ve);
void printList(const vector <Employee *> & Ve);

int main()
{
	
	vector <Employee *> VEmp;
	
	getInput(VEmp);
	
	printList(VEmp);
	
	system("pause");
	return 0;
}

// Contain a loop that will give the user an option to enter information
// about an hourly employee or a salaried employee. Depending on the user's
// choice, collect the appropriate input information from the user and use
// this information to dynamically construct a derived class object. Assign
// the address of the dynamically created derived class object to an element
// of the Ve vector.
void getInput(vector <Employee *> & Ve)
{
	// employee id
	int empID;
	// number of hours worked
	double hours;
	// pay rate
	double payRate;
	// salary
	double salary;
	// user's choice
	int option;

	// do until option 3 is entered
	do
	{
		// display options
		cout << "Enter 1 for Hourly Employee" << endl;
		cout << "Enter 2 for Salaried Employee" << endl;
		cout << "Enter 3 to stop:  ";

		// read option
		cin >> option;
		cout << endl;

		// process option
		switch (option)
		{
		case 1:
			// read employee ID
			cout << "Enter the ID: ";
			cin >> empID;
			// read number of hours worked
			cout << "Enter the number of hours worked: ";
			cin >> hours;
			// read pay rate
			cout << "Enter the pay rate: ";
			cin >> payRate;
			// dynamically construct a HourlyEmployee object and 
			// push back into vector
			Ve.push_back(new HourlyEmployee(empID, hours, payRate));
			break;
		case 2:
			// read employee ID
			cout << "Enter the ID: ";
			cin >> empID;
			// read salary
			cout << "Enter the salary: ";
			cin >> salary;
			// dynamically construct a SalariedEmployee object and 
			// push back into vector
			Ve.push_back(new SalariedEmployee(empID, salary));
			break;
		case 3:
			break;
		default:
			cout << "Error: invalid option" << endl;
		}

		cout << endl;
	} while (option != 3);
}

// Loop through the elements of the Ve vector and call the printPay() function
// of each of the dynamically allocated objects.
void printList(const vector <Employee *> & Ve)
{
	for (size_t i = 0; i < Ve.size(); i++)
	{
		Ve[i]->printPay();
	}
}
Your program only dynamically allocates memory in the getInput function. getInput is making an implicit contract with main that says "You give me a vector and I'll fill it up, but you're responsible for that memory when I'm finished." Since these allocations don't happen in any of your class methods, then destructors will do you no good. At the end of main() you should iterate over the vector and free the memory at each element.

1
2
3
4
5
6
7
8
9
void cleanUpList(vector <Employee *> & Ve)
{
    for (size_t i = 0; i < Ve.size(); i++)
    {
        delete Ve[i];
    }

    Ve.clear();
}
Last edited on
booradley60 - thank you. I am "not allowed to touch main" per the instructor.

At this point no you do not need to worry. The memory will be cleaned up at the end of the main function. Your code does not have any tasks that rely on flushing buffers/text writes etc that rely on a destructor so for now you can ignore it.

Your instructor has most likely done this on purpose so you can focus on the core problem while developing fundamental knowledge.
Topic archived. No new replies allowed.