overloaded << for linked list objects

Hi there,

I have a linked list with each node holding an employee object. The employee class has name and salary data. I am currently trying to create an overloaded ostream operator << that outputs my list of employees.

For example (should print out: Name1, Salary1, \n Name2, Salary2, \n etc.):

1
2
ListOfEmployee list1;
cout << list1;


My current code is giving me some errors even though the overloaded function is a friend so I am not sure why this is happening
1. identifier head is undefined
2. next is inaccessible

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
// ListOfEmployee.h

#ifndef LISTOFEMPLOYEE_H
#define LISTOFEMPLOYEE_H
#include "EmployeeListNode.h"
#include <iostream>

using namespace std;

class ListOfEmployee
{
public:
	ListOfEmployee();
	~ListOfEmployee();

	friend ostream& operator <<(ostream output, ListOfEmployee emp);

	void insertAtFront(string, double);
	void deleteMostRecent();
	double getSalary(string name);

private:
	EmployeeListNode* head;
};

#endif 

//ListOfEmployee.cpp

#include "pch.h"
#include "ListOfEmployee.h"



ListOfEmployee::ListOfEmployee()
{
	head = NULL;
}

ListOfEmployee::~ListOfEmployee()
{

}

void ListOfEmployee::insertAtFront(string name, double sal)
{
	ListPtr n = new EmployeeListNode(name, sal);
	n->next = head;
	head = n;

}
void ListOfEmployee::deleteMostRecent()
{
	ListPtr temp = NULL;
	if (head != NULL)
	{
		temp = head;
		head = temp->next;
		delete temp;
	}
}

double ListOfEmployee::getSalary(string name)
{
	ListPtr current = head;
	while (current->next != NULL)
	{
		if (current->emp.name == name)
		{
			return current->emp.salary;
		}
		else
		{
			current = current->next;
		}
	}
}

ostream& operator <<(ostream output, ListOfEmployee emp)
{
	
	ListPtr current = head; // ERROR: identifier head is undefined
	while (current->next != NULL) // ERROR: next is inaccessible 
	{
		//output name and salary for employee nodes
	}
	return output;
}

//EmployeeListNode.h

#ifndef EMPLOYEELISTNODE_H
#define EMPLOYEELISTNODE_H
#include "Employee.h"
using namespace std;

class EmployeeListNode
{
	friend class ListOfEmployee;
public:
	EmployeeListNode(string n, double s);
private:
	Employee emp;
	EmployeeListNode* next;
};

typedef EmployeeListNode* ListPtr;

#endif 


//Both the EmployeeListNode and ListOfEmployee are friend classes of Employee
Last edited on
1
2
3
4
5
6
7
8
9
10
ostream& operator <<(ostream output, ListOfEmployee emp)
{
	
	ListPtr current = head; // ERROR: identifier head is undefined
	while (current->next != NULL) // ERROR: next is inaccessible 
	{
		//output name and salary for employee nodes
	}
	return output;
}


In a function, the following variables exist:
1) Global variables that exist everywhere.
2) Variables passed in as parameters
3) Variables created in that function
4) In class member functions, class member variables

Which of these is "head" in the function above? None of them
Thanks for the reply mate. How is the head variable in this function different to the head var in the above function 'ListOfEmployee::getSalary(string name)'? This function can access head without any problems. That is what i can not understand

Last edited on
Should you use the head of emp?

Do you really want to make a copy of the list every time you print it?
Why doesn't your compiler scream that std::ostream is non-copyable?

I would not make operator<< a friend. It is just syntactic sugar:
1
2
3
4
5
std::ostream& operator<< ( std::ostream& lhs, const ListOfEmployee& rhs )
{
  rhs.printList( lhs );
  return lhs;
}


Then you obviously need:
1
2
3
void ListOfEmployee::printList( std::ostream& output ) const {
  // code
}

There you have necessary access and you can remain const correct too.


PS. Who does deallocate the dynamically allocated list nodes?
Thank you for your reply.

I thought I had to use a friend(stand alone function) function unless, the lhs was automatically the object on which the method is called?

I tried the following code and got lots of errors:
http://i68.tinypic.com/2j3rur8.png

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
//.cpp functions
void ListOfEmployee::printList(ostream& output) const {
	current = head;
	while (current->next != NULL)
	{
		cout << "Employee name: " << current->emp.name << " ID: "<<current->emp.salary;
		current = current->next;
 	}
	
}

ostream& operator<< (ostream& lhs, const ListOfEmployee& rhs)
{
	
	rhs.printList(lhs);
	return lhs;
}

//ListOfEmployee.h

#ifndef LISTOFEMPLOYEE_H
#define LISTOFEMPLOYEE_H
#include "EmployeeListNode.h"
#include <iostream>
using namespace std;

class ListOfEmployee
{
public:
	ListOfEmployee();
	~ListOfEmployee();

	
	std::ostream& operator<< (std::ostream& lhs, const ListOfEmployee& rhs);
 // ERROR: too many parameters for this operator function,
// function definition for 'operator<<' not found

	void printList(std::ostream& output) const;

	void insertAtFront(string, double);
	void deleteMostRecent();
	double getSalary(string name);

private:
	EmployeeListNode* head;
	EmployeeListNode* current;
	EmployeeListNode* temp;
};

#endif  


regarding who deallocates the dynamically allocates list nodes. im not quite sure what you're asking. my EmployeeListNode.cpp is as follows if that's what you mean:

1
2
3
4
5
6
7
8
9
10
#include "pch.h"
#include <iostream>
#include "EmployeeListNode.h"

EmployeeListNode::EmployeeListNode(string n, double s)
{
	emp.salary = s;
	emp.name = n;
	next = NULL;
}
Last edited on
Thanks for the reply mate. How is the head variable in this function different to the head var in the above function 'ListOfEmployee::getSalary(string name)'?


That's a class function. It's part of the ListOfEmployee class. A class function has access to all the member variables of that class.
Thanks repeater. Is there any way I could get 'friend ostream& operator <<..' function to have access to all the member variablse of the ListOfEmployee and EmployeeListNode classes? i.e. the head and next variables

I have tried lots of different things and I still can not get this code to work! I have also tried keskivertos way and got some errors. Some coding help would be appreciated :D
Last edited on
i have got it working, although I had to make the emp and next variables in the EmployeeListNode class public instead of private.. which is not ideal. Is there anyway to do it and keep the variables private?

1
2
3
4
5
6
7
8
9
10
11
12

ostream& operator<< (ostream& lhs, ListOfEmployee& rhs)
{
	
	rhs.current = rhs.head; 
	while (rhs.current->next != NULL) 
	{
		lhs << "Employee name: " << rhs.current->emp.getName() << " ID: " << rhs.current->emp.getSalary() << "\n";
		rhs.current = rhs.current->next;
	}
	return lhs;
}
Last edited on
Make the operator a friend of the class, and it will then have access to the class' private variables.
I have added the friend function to EmployeeListNode and 'ListOfEmployee& rhs' is then undefined?
'ListOfEmployee& rhs' is then undefined?

Are you asking us or telling us?

Let's see the code you've got now.
Forward declare class ListOfEmployee; for the EmployeeListNode.
It works perfect now thanks a lot guys. I made the operator a friend of both the List and Node classes. Also forward declared class ListOfEmployee for Node class.

Now i just need to do some research so i know what forward declaring a class means and why i done it!

Thanks again
Topic archived. No new replies allowed.