Constructors are kicking me in the rear!

Pages: 123
Not writing anything in the cpp file doesn't make sense at all. It's the most reasonable place for all of this code to go.

Like I said earlier, you could use initialisation lists for some of these constructors, but given what you've told me so far you won't have covered them yet. So the cpp file seems right to me.

Right, I don't normally hand out full code because we usually get a lot of people on these forums looks for handouts. On this case, I'll make a bit more of an exception, because I feel you genuinely want to learn it and I think it's the best way to show you.

That way, I can go through it line by line as well.

So, here it goes...
1
2
3
4
5
addressBook::addressBook( char *fName, char *lName, char *address )
{
   PERSON p = { fName, lName, address };
   addPerson( p );
}


Probably way simpler than you thought it'd be.

So, what are we doing. We haven't been given a person object, but we've been given the data to create on with. So that's what we'll do.
 
PERSON p = { fName, lName, address };

That creates a person object. Rather than hard coding text values like you have in your "TEST1" example a couple of posts ago, we've been given those values in the arguments. So we'll just pass them straight in.

Then we need to add that person to the book. That's easy enough, we've done it before and there's a function for it. So we'll use it.
 
addPerson( p );

Remember that "p" in this case is the person object we've just created using the data passed in.

And that's it. :-)
And since I have to have this done today, I might as well show you what I've done so far on the array requirement. I'm a little rusty on arrays, and I still have no idea how to pop it into addPerson, but here's what I have:

my header:

addressBook( PERSON *p, int size );

my addressbook.cpp:
1
2
3
4
5
6
7
8
9
10
11
addressBook::addressBook( PERSON *p, int size )
	{
		int size = 25;
		for ( int i = 0; i < size; i++ )
   {
       PERSON x[3] = { 
{"BOB", "Robertson", "1313 Mockingbird ln"},
{"Joe", "Smith", "1023 Anywhere"},
{"Jane", "Doe", "555 self place"}
};
   


and I haven't sorted out how to get that into main yet. Assuming it's even done right.

};
Last edited on
Ok, I would have to go with holy cr@p! I can't believe it's that simple. I have been killing myself for days, and it never occurred to me to pass first, last , and address through PERSON, and then call the actual info through the constructor. I had though about using the PERSON function like this, but just passing the actual names and such into it. That of course would have negated calling them them through the constructor in main. I didn't realize I could do it this way. I thought that since fname, lname and Address are all already a part of the PERSON struct that you couldn't do that.

Would I still have to use the * when I called them into PERSON?

1
2
3
4
5
addressBook::addressBook( char *fName, char *lName, char *Address )
{
   PERSON p = { *fName, *lName, *Address };
   addPerson( p );
}


or is that wrong?
That's wrong.

The * is a part of the type. You want to pass just the identifier.

If you prefer, you can write the arguments in the form char* fName if it helps. That is with the star next to the type, rather than the identifier. The compiler doesn't care, it's whatever makes sense to you.

I put the * next to the identifier out of convention.
When I do it without the star, i get errors for all three saying:

a value of type "char*" cannot be used to initialize an entity of type "char"


And when I throw the star in there, i runs fine, but nothing comes up in the addressbook when I tell it to print the addressbook.
OK, I got it to accept it, I had to go and delete and retype the star, for whatever reason, so no more errors, but it still doesn't show up in the program.
I'm gonna repost where I'm at in the code, because I've added and removed and added stuff over the last few days:

My Header:

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
#ifndef _ADDRESSBOOK
#define _ADDRESSBOOK
const int MAXADDRESS = 25;
struct PERSON
{
 char fName[25];
 char lName[25];
 char Address[100];
};
class addressBook
{
private:
 PERSON people[MAXADDRESS];
 int head;
 int tail;
 
public:

 bool addPerson(const PERSON &p);
 bool getPerson(PERSON &p);
 bool findPerson(char *lastName, PERSON &p);
 bool findPerson(char *lastName, char *firstName, PERSON &p);
 void printBook();

 static addressBook *Instance();
 PERSON part1;
  addressBook();
	
 addressBook ad();
 addressBook myBook();
 addressBook newBook();

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

 addressBook( PERSON p );

 addressBook( PERSON *p, int size );
	 
	
};
#endif 


MY addressbook.cpp:

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

#include <iostream>
#include "addressBook.h"
using namespace std;
addressBook::addressBook()
{
 head = 0;
 tail = -1;
}

addressBook::addressBook( PERSON p )
	
{
   addPerson( p );
};

addressBook::addressBook( char *fName, char *lName, char *Address )
	
{
   PERSON p = { *fName, *lName, *Address };
   addPerson( p );
}

addressBook::addressBook( PERSON *p, int size )
	{
	
		for ( int i = 0; i < size; i++ )
   {
       PERSON p[3] = { 
{"BOB", "Robertson", "1313 Mockingbird ln"},
{"Joe", "Smith", "1023 Anywhere"},
{"Jane", "Doe", "555 self place"}
};
	   addPerson(p[3]);
   }

};

bool addressBook::addPerson(const PERSON &p)
{
 if(head < MAXADDRESS)
 {
 people[head] = p;
 head++;
 if(tail == -1)
 tail++;
 return true;
 }
 return false;
}
bool addressBook::getPerson(PERSON &p)
{
 if(tail >=0)
 {
 if(tail >= head)
 tail = 0;
 p = people[tail];
 tail++;
 return true;
 }
 return false;
}
bool addressBook::findPerson(char *lastName, PERSON &p)
{
 for(int i = 0; i < head; 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 < head; 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 < head; i++)
 {
 cout << people[i].fName << "\t" << people[i].lName << "\t" << people[i].Address << endl;
 }
}


and my main.cpp:

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

#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 EXIT = 0;
int main()
{

	addressBook ad;
	addressBook myBook;


	PERSON me = {"Someone", "Somebody", "123 house"};

	myBook.addPerson(me);


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

int selection;

PERSON p;


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 PRINT :
				
				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 << "0. Exit this program " << endl;
	cin >> selection;

	return selection;

}

void waitKey()
{

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

	getch();
	fflush(stdin);

}


Mabey I just screwed something up
Last edited on
Doesn't look like you're printing the book you've created using that constructor (the one you called newBook).

You'll need newBook.printBook();

To clarify, when you make the temporary person in the constructor, there shouldn't be any stars:

 
PERSON p = { fName, lName, Address };
Yeah, I caught that, but it still gives me errors if I dont put them, and it doesnt place the info in the program if I do. As for the printbook, I just caught that right before I came back here, I realized I had forgotten to add that at the end of main with the other addressbooks.

what do you think could be causing the errors?
Last edited on
yeah, I caught the printbook thing, and realized I hadn't added the new addressbook to it. As for the PERSON p =, if I don't add the star, I get errors, and if I do add the star, I don't get errors, but then it doesn't store the info to the addressbook, am I missing something?
Oh I see what's happened. Your teacher has created the strings using the array method, rather than the pointer method.

I guess the easiest fix would be this...

1
2
3
4
5
6
7
8
9
addressBook::addressBook( char *fName, char *lName, char *Address )
	
{
   PERSON p;
   strcpy_s( p.fName, fName );
   strcpy_s( p.lName, lName );
   strcpy_s( p.Address, Address );
   addPerson( p );
}


That should do it. strcpy_s is a function used for copying strings. It the first string you give it is the destination, the second is the source. This will only work on C-style strings.

More information here: http://www.cplusplus.com/reference/cstring/strcpy/

I hate C-style strings...
Yeah, I had seen in our forums for class that everyone was trying it with the char *fName~ and not getting it either, (which makes me feel a little better)
I'm assuming he's just taking us slow, but this does seem to be a bit of extra work. I had tried this once as well, but didn't realize I could pass it to the PERSON p, so just gave up on it.

As far as I know, so far nobody has been able to get this to print onto the screen in the program, even the one girl who said she was using this method. Even with this, it still isn't coming up with the info. Maybe its something wrong with the starter code he gave us.

When you get a chance, could you have a look at my array and tell me what I'm doing wrong or missing. It's been a while since I've done one, and I'm looking up to formatting info about it now from the teachers level one lectures I still have from years ago in my level 1 class, but any help would be appreciated.
It'll be a quick post because I'm off to bed.

With your array...

Get rid of the int size = 25; statement.

Loop statement is fine.

Inside the loop, you should have a call to addPerson passing in the person at index i of the array passed in.
Cool, I'm surprised I actually did something right for a change. Thanks again for all your help.
So here's what it was supposed to be...


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
// header
#ifndef _ADDRESSBOOK
#define _ADDRESSBOOK
const int MAXADDRESS = 25;
struct PERSON
{
 char fName[25];
 char lName[25];
 char Address[100];
};
class addressBook
{
private:
 PERSON people[MAXADDRESS];
 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 getPerson(PERSON &p);
 bool findPerson(char *lastName, PERSON &p);
 bool findPerson(char *lastName, char *firstName, PERSON &p);
 void printBook();
};
#endif 


and the constructors in .cpp were supposed to look like this....

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
 //Here are the constructors
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);
}
That's more or less what you had, wasn't it?

I didn't see your final array constructor, but the other two look more or less dead on.
He seems to have used a constant for PERSON on both the array and the standard PERSON struct, and the same method shown to me from iHutch105 for the string. He didn't show anything for how to get it all to print, (mostly because I don't think he cared).

The only main difference I see that I did wrong was that I put my array info where I should not have, and didn't call the array to const PERSON p like I should have. I also forgot to add the : head(0), tail(-1) as well, which sucks because I had it in there before I submitted it, but then took it out because I didn't see the need for them to be there.
That's a shame. The const won't have made a difference in functionality, but I guess it's good practice.

Sounds like you did ok, though. Well done.
my array constructor had the

1
2
3
4
5
PERSON p[] = { 
{"Glenn", "Stevenson", "1313 Mockingbird ln"},
{"Joe", "Smith", "1023 Anywhere"},
{"Jane", "Doe", "555 self place"}
};


In it, and I didn't set it as a const PERSON p[], just PERSON p. I ended up with a "C" grade, which is better than an F.

Now I have to switch the

PERSON people[MAXADDRESS];

array into a vector, which I think, (and I'm still reading up on this so I may be wrong), should look something like this...

1
2
3
4
5
6
7
8
9
10
11
12
13
PERSON vector <int> v;  

// OR

PERSON vector <int> v(25);

// Or possibly even

PERSON vector <int> v;  

// Followed by something like this

v.reserve(25);  


I'm still reading up on Vectors, so I'm not sure what to do.

After that I have to do this:

Add a sort function that will sort your addressBook by last name.
There are several different sorting algorithms that you can use. You might want to investigate using a bubble sort. Examples can be found online but if you have problems finding one let me know and I will supply one for you.


I looked up a bubble sort example, but it's all gibberish to me right now, I'm gonna have to play with it on a practice program before I can begin to understand what it does and why.
Good luck. :-)
Pages: 123