I need to define a read and a print function for a class that has an array of objects as a private variable. I have to read in objects from a text file and print them to the screen. To do this I need to overload the << and >> operators. I understand I need to use loops to read and print the information stored in the array but I’m not sure how to accomplish this. My lecturer has given us a skeleton code which is basically function prototypes and the main function which I need to stick to. I understand how this works with public structs as I have done this exact scenario using that but the private variables of class’ are tripping me up.
class EmployeeList {
public:
//Constructors
EmployeeList();
EmployeeList(istream&);
//Accessors
bool isEmpty() const;
bool isFull() const;
int size() const; //Number of employees in list
Employee item(int i) const; //i'th employee
//Mutators
void setItem(int i,const Employee& e);
//I/O functions, sets the i'th emplyee to e
void read(istream&);
void print(ostream&) const;
private:
enum {MAXSIZE = 100};
Employee list[MAXSIZE];
int count; //Number of employees in the current list
};
EmployeeList::EmployeeList() {
count = 0;
}
EmployeeList::EmployeeList(istream& in) {
//list[MAXSIZE] = in;
}
bool EmployeeList::isEmpty() const {
return (count == 0);
}
bool EmployeeList::isFull() const {
return (count == MAXSIZE);
}
int EmployeeList::size() const {
return count;
}
Employee EmployeeList::item(int i) const {
}
void EmployeeList::setItem(int i, const Employee& e) {
}
void EmployeeList::read(istream& in) {
Employee tempList;
while (in >> tempList) {
}
}
void EmployeeList::print(ostream& out) const {
for (int i=0; i < size(); i++) {
}
cout << out;
}
The above part is the Class EmployeeList while the below part are overloading functions. The commented out parts are ideas that I thought might work but didn’t.
istream& operator>>(istream& in, EmployeeList& l) {
l.read(in);
return in;
}
ostream& operator<<(ostream& out, const EmployeeList& l) {
l.print(out);
return out;
}
Below is the main function given to us.
int main() {
authorInfo();
ifstream infile("a1in.txt");
if(!infile) {
cout << "file 'alin.txt' not found.";
return EXIT_FAILURE;
}
EmployeeList theList(infile);
cout << endl;
cout << theList.size() << " employees read:\n" << theList << endl;
process(theList);
return EXIT_SUCCESS;
}
Hope someone can steer me in the right direction! Let me know if you need more of the code. Thanks!
EDIT:
Employee read and print functions:
void Employee::read(istream& in) {
in >> name >> id >> salary;
}
void Employee::print(ostream& out) const {
out << getName() <<" "<< getID() <<" "<< getSalary() << endl;
}
Employee overloading:
istream& operator>>(istream& in, Employee& e) {
e.read(in);
return in;
}
ostream& operator<<(ostream& out, const Employee& e) {
e.print(out);
return out;
}
EDIT 2: Updated read() function. The line with the while is where the error is.
void EmployeeList::read(istream& in) {
Employee inEmployee;
while (in >> inEmployee && count < MAXSIZE) {
list[count] = inEmployee;
count++;
}
}
EDIT 3: Here is the print() function I have so far. It does indeed print but I get the default constructor information rather than information from the file. Is this a read or print function issue? I’m thinking read function still.
void EmployeeList::print(ostream& out) const {
cout << endl;
for (int i=0; i < count; i++) {
out << list[count];
}
}
Array Bounds
In your class, you have:
Given this, there is an error the code you tried:
listonly has elements fromlist[0]tolist[MAXSIZE - 1].list[MAXSIZE]is one past the end of the array, and is invalid.Constructors
That said, I’d strongly recommend against having a constructor that takes an
istream&. It is far better to construct an empty object with the default constructor, then use itsread(istream&)method (viaoperator <<) to load the data. In other words, rather than:use:
If you’re required to have a constructor that takes an
istream&, just have it callread()after initializing the object:Note that only one constructor is called, so the initialization in
EmployeeList::EmployeeList()does not happen inEmployeeList::EmployeeList(istream&). I hear the new version of C++ deals with this unnecessary repetition, but for the time being that’s where we are.Naming
Another thing: your code will be less confusing with better variable names. In this case:
Don’t say
tempListbecause it’s not a “temporary list”, it’s a singleEmployeethat has been read. Better would be: