Friend function and overloaded operators

Pages: 12
So I'm just having a super-dee-dooper fun time with overloaded operators and the friend function. I have an addressbook, and for my assignment I have to use the friend function to overload a few different operators. I think I understand how to type the friend function out to tie it to my class, and how to utilize it in my associated .cpp file, but I'm not all that sure as to how to do what the assignment is asking as far as the actual work these things should be doing. I'll post my code and assignment requirements so you can see where I'm at and hopefully somebody can guide me in what I need to do. I kind of have an idea of what needs to be done, but I don't know what the code is supposed to look like as far as looking into whats in the addressbook already and how its accessed.

Here is my header file :

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
#ifndef _ADDRESSBOOK
#define _ADDRESSBOOK
#include <vector>
#include <iostream>

using std::istream;
using std::ostream;

const int MAXADDRESS =25;

struct PERSON
{
 char fName[25];
 char lName[25];
 char Address[100];
};

class addressBook
{
private:
	vector <PERSON> people;

 int head;
 int tail;

public:

 addressBook();

 addressBook(const PERSON &p);

 addressBook(const PERSON p[], int size);

 addressBook(char *fName, char *lName, char *address);



 bool addPerson(const PERSON &p);
  bool sortcomp(const PERSON& p1, const PERSON& p2);
 bool getPerson(PERSON &p);
 bool findPerson(char *lastName, PERSON &p);
 bool findPerson(char *lastName, char *firstName, PERSON &p);
 void bubbleSort(int *array,int length);
 void printBook();
 void sort();

friend ostream &operator << (ostream &, addressBook &);
friend istream &operator >> (istream &, addressBook &);

};
#endif 


And here is my addressbook.cpp file :

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
#include <iostream>
#include "addressBook.h"
using namespace std;

addressBook::addressBook()
: head(0), tail(-1)
{
 
}

addressBook::addressBook(const PERSON &p)
: head(0), tail(-1)
{
 addPerson(p);
}

addressBook::addressBook(const PERSON p[], int size)
: head(0), tail(-1)
{
 for(int i = 0; i < size; i++)
 addPerson(p[i]);
 
}

addressBook::addressBook(char *fName, char *lName, char *address)
: head(0), tail(-1)
{
 PERSON tmp;
 strcpy(tmp.fName, fName);
 strcpy(tmp.lName,lName);
 strcpy(tmp.Address, address);
 addPerson(tmp);
}

bool addressBook::addPerson(const PERSON &p)
{
 
 
 people.push_back(p);

 if(tail == -1)
 tail++;
 return true;
 
}
bool addressBook::getPerson(PERSON &p)
{
 if(tail >=0)
 {
 if(tail >= people.size())
 tail = 0;
 p = people[tail];
 tail++;
 return true;
 }
 return false;
}
bool addressBook::findPerson(char *lastName, PERSON &p)
{
 for(int i = 0; i < people.size(); i++)
 {
 if(!stricmp(people[i].lName, lastName))
 {
 p = people[i];
 return true;
 }
 }
 return false;
}
bool addressBook::findPerson(char *lastName, char *firstName, PERSON &p)
{
 for(int i = 0; i < people.size(); i++)
 {
 if(!stricmp(people[i].lName, lastName) && !stricmp(people[i].fName, firstName))
 {
 p = people[i];
 return true;
 }
 }
 return false;
}


void addressBook::printBook()
{
 for(int i = 0; i < people.size(); i++)
 {

 cout << people[i].fName << "\t" << people[i].lName << "\t" << people[i].Address << endl;
 }
}

 bool addressBook::sortcomp(const PERSON& p1, const PERSON& p2)
{
	int i;
    int result = std::strcmp(p1.lName, p2.lName) ;

    if ( result > 0 )
        return true ;
    if ( result < 0 )
        return false ;
    return std::strcmp(p1.fName, p2.fName) > 0 ;

	 for(i=0;i< people.size();i++)
    {
       for ( unsigned i=1; i< people.size(); ++i )
            if ( sortcomp(people[i-1], people[i]) )
            {
                std::swap(people[i-1], people[i]) ;
                result = true ;
            }
			sort();

}
 }

ostream &operator << (ostream &output, addressBook &ab)
	{
		addressBook ad;
		ad.sort();
		

		output
		
}



And here is my main.cpp file :

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
#include <iostream>
#include <cstdlib>
#include <conio.h>
#include "addressBook.h"


using namespace std;
int printMenu();
void waitKey();

const int ADDPERSON = 1;
const int GETPERSON = 2;
const int FINDLAST = 3;
const int FINDBOTH = 4;
const int PRINT = 5;
const int NAMESORT = 6;
const int EXIT = 0;


int main()
{
	PERSON p;
	addressBook ad;
	addressBook myBook;
	addressBook newBook;
	addressBook newerbook;
	

	PERSON me = {"Johnny", "Rocket", "923 go"};


	ad.addPerson(me);


	addressBook newbook("TEST", "TEST2", "1234");

	
	

	
	
	
	
	

int selection;



bool status;
char lName[50];
char fName[50];
		

		selection = printMenu();
		while(selection != EXIT )
		{
		switch(selection)
			{

			case ADDPERSON :
				cout << "Enter First Name " << endl;
				cin >> p.fName;
				cout << "Enter last Name " << endl;
				cin >> p.lName;
				cout << "Enter Address " << endl;
				cin >> p.Address;
				status = ad.addPerson(p);
				if(status == false)
					cout << "Sorry There is no more room in the address book " << endl;
				else
					cout << "Thanks for your Entry " << endl;

				waitKey();	
				break;
			case GETPERSON :
				status = ad.getPerson(p);
				if(status)
					cout << p.fName << "\t" << p.lName << " " << p.Address << endl;
				else
					cout << "Sorry The address book is empty " << endl;

				waitKey();

				break;
			case FINDLAST :
				cout << "Enter a last name " << endl;
				cin >> lName;
				status = ad.findPerson(lName,p);
				if(status)
						cout << p.fName << "\t" << p.lName << " " << p.Address << endl;
				else
					cout << "Sorry, Name not found " << endl;

				waitKey();
				break;

			case FINDBOTH :
				cout << "Enter last name " << endl;
				cin >> lName;
				cout << "Enter first name " << endl;
				cin >> fName;
				status = ad.findPerson(lName, fName,p);
				if(status)
					cout << p.fName << "\t" << p.lName << " " << p.Address << endl;
				else
					cout << "Sorry, Name not found " << endl;

				waitKey();
				break;

			case NAMESORT :
				ad.sort();
				newbook.sort();
				myBook.sort();
				cout << "Your addressbook has been alphabetically sorted, choose print from the main menu to see the results " << endl;
				waitKey();
				break;
				
			case PRINT :
				
				newbook.printBook();
				ad.printBook();
				myBook.printBook();
				waitKey();
				break;
			case EXIT :
				cout << "Thanks for using the address book " << endl;
				exit(0);
		}
			selection = printMenu();
		}
};

int printMenu()
{
	

int selection;

	system("CLS");
	cout << "1. Add A Person" << endl;
	cout << "2. Get A Person " << endl;
	cout << "3. Find A person By Last Name " << endl;
	cout << "4. Find A person By First and Last Name " << endl;
	cout << "5. Print the address book " << endl;
	cout << "6. Sort by last name " << endl;
	cout << "0. Exit this program " << endl;
	cin >> selection;

	return selection;

};

void waitKey()
{

	cout << "Press a key to continue " << endl;
	while(!kbhit())
		;

	getch();
	fflush(stdin);

};


And finally, here is my assingment :

Enhance your address book with the following functionality:
1.) Use friend function to overload the stream insertion '<<' operator, so that you can directly print out the contents of the next person in the address book. You should set this up so that after the last person in the address book is printed, then printing will start over from the beginning.
AddressBook ab;
cout << ab; //Should print the first person in the book
cout << ab; //Should print the second person in the book

2. Overload the '+=' so that a new PERSON can be added to the end of the address book.

PERSON p = {"Bob", "Roberts", "123 Anywhere Rd."};
ab+= p; //Adds Bob to the end of the address book




3. Overload the '[]' operator so that a person can directly get at the element of the address book they are searching for.
PERSON p;
p = ab[3]; // Assigns the 4th person in the addressBook to p


I've been trying to figure this out for a week so far, and all I've managed to get is a better understanding of how a friend function and overloaded operator should look like, so any help would be greatly appreciated, Thanks!
Last edited on
So for this question :

1.) Use friend function to overload the stream insertion '<<' operator, so that you can directly print out the contents of the next person in the address book. You should set this up so that after the last person in the address book is printed, then printing will start over from the beginning.
AddressBook ab;
cout << ab; //Should print the first person in the book
cout << ab; //Should print the second person in the book


I included the sort, but how do you make it so the program picks the names out one at a time?

1
2
3
4
5
6
7
8
9
ostream &operator << (ostream &output, addressBook &ab)
	{
		addressBook ad;
		ad.sort();
		

		output
		
}
Last edited on
Well, I managed to get the second part of the assingment to print out, and then I realized I'm not supposed to use the friend function to do it..oi. At least I got it to work though, thats something positive! Here's what I have so far in my addressbook.cpp file :

1
2
3
4
5
6
7
8
9
ostream &operator << (ostream &output, addressBook &ab)
	{
		PERSON me2 = {"CJ", "MZ", "123"};
		ab.addPerson(me2);
			

		return output;
		
};


Now I just have to figure out how to switch it over to a regular overloaded operator. Still no clue how to do the first part though, any help would be appreciated!
Ok, for the second part, can somebody tell me if this looks right? It rints out at the end of the list like its required, but I have to do the function in my .cpp, and the rest in my main.

My addressBook.cpp entry :

1
2
3
4
5
6
7
8
addressBook addressBook::operator +=(const PERSON &p)
{
	addressBook ad;
	
	addPerson(p);
		
		return ad;
}


And my main.cpp entry :

1
2
3

	PERSON me2 = {"CJ", "MZ", "123"};
ad+=me2;


So did I do that the right way?
Apparently I was over thinking how this is done. My teacher walked me though this stuff, and it was unbelievably simple compared to what I was trying to do.
Hey xanthian! I actually worked on this quite a bit and was wondering what your teacher eventually told you to do?
Well, the += friend overload only needs access to the addPerson function and a return to the addressbook via the this function, the << overload needed an instance of the PERSON struct, access to a referenced version of the getperson function, an output that uses the PERSON instance, and a return to the output, and the [] overload just needed a reference to my vector.
I was trying to use while statements to access my findperson functions and get person functions, plus my sorter and a whole slew of other things. One of them actually caused an infinite loop that accessed an empty spot in memory and caused a pretty cool show on the screen, but did nothing towards the assignment.
Wow that seems pretty complex... I am not very good at programming but I troll forums trying to learn as much as I can before I go back to school... Is there any way you can post what you came up with?? If you have time...
Yeah, I can post the code on Monday, if you don't mind waiting. This is still a current assignment for my class, and I can't post actual solutions until after they are posted by the teacher, just in case someone from the class happens upon this thread. After Monday though, I would be happy to post the code and explain whats going on as I was shown.

Plus, this is the level two class material. If your interested in getting a heads up on the level one stuff, my teacher offers free access to his level one class to anyone, just follow this link:

http://programming.msjc.edu/cpp/Home.aspx

That can get you up to speed and ready to learn about classes, constructors, vectors, enumerators, overloaded operators and more!
Last edited on
The [] operator accesses the vector in the function body. You would want an overloaded operator that looks a bit like this:

1
2
3
4
5
6
7
8
9
10
11

// .h
className operator[](int x); //calls an int because an array has to return an int

//.cpp

className className::operator[](int x)
{
  //return an instance of your vector and reference the array in the function
}


Hope that helps.
thanks for all the great info! Unfortunately I am still stumped :(... return an instance of the vector?? so you are basically returning a PERSON struct? that is not of type int... I am confused and confounded haha!
I am in your class and I am completely stuck, can you explain what Stevenson told you? Sorry for being so late to ask
You have to return a value in the operator function, like return 0; Except in this case, you need to return the vector you created last week. Say you had created a vector called peeps, you would need to return that, along with a reference to the int your using in your overload. does that help?
addressBook &addressBook::operator += (const PERSON &p)
{
addressBook abc;
PERSON p = {"Glenn", "Stevenson", "1313 Mockingbird ln."};
abc+=p;
abc.addPerson(p);
return abc;
}
This is the code I have for 2 right now, and I know the return is wrong but I cant figure it out
I made this same mistake, basically you are waaay overdoing it. You only need to reference addPerson(p) like you have, minus the abc. reference your creating from the instance of addressBook that you don't need, and then you need to return a pointer to "this".
What this basically does is take the info from PERSON that you pointed to via "p", and then add it to the addressBook through the this command via a pointer *. All of that takes the += and make it do all that work so that in main you can take an addressbook, lets say book1 and point it to some variable of PERSON you've created, say "me"

You main would then look like this:
1
2
3
4
5

PERSON me = {"FIRST", "LAST", "1234 ADDRESS"};

book1+=me;


This is done without the need of the rest of the addressBook, so you could add to it just from there.
Last edited on
I'll keep an eye out on this thread for a little while tonight if you need any more help.
Wow that is so simple its frustrating how much I was over thinking it. How did you test the 3rd operator? Cause I think I have it right but I dont know what to put in main to find out
I know I have it done correctly, the teacher walked me through it, but I never figured out how to test it since whenever I try to put in p = ab[3]; it give me an error in the = operator. I tried cout << ab[3], which works when you comment out everything in the addressbook out except the print menu and waitkey in main

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

cout << ab[3];
/*
int selection

...

		}
			selection = printMenu();
		}
	*/	
};

int printMenu()
{
well I got the first and second ones to work for sure but the third one was wrong, is there any extra explanation you can add for that one?
and thank you so much for your help, this assignment was really confusing me before
Pages: 12