Input arg. as name of object

I'm trying to have a function take in a couple arguments, the last of which (an int) I want to convert to ASCII and use the character as the name of an object. When I try to compile, it says "‘name’ has a previous declaration as ‘char name’"
How do I use the input as a name?

1
2
3
4
5
6
7
8
9
10
11
12
13
// user.h
struct userData {
	int id;
	string username;
	int birthyear;
	int zipcode;
	vector<int> friends;
};

class User {
	public:
	User(string name, int year, int zip, int &numusers);
	// Creates new user, and initializes all fields 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// user.cpp
// #includes

User::User(string _name, int _year, int _zip, int &numusers)
	// Creates new user, and initializes all fields
{
	char name = '0' + numusers;
	userData *name = new userData;
	name->id = numusers;
	numusers++;
	name->username = _name;
	name->birthyear = _year;
	name->zipcode = _zip;
	name->friends = new vector<int> friends;
}
Unfortunately, you can't name a variable in your function the same as one of its arguments, but you might be able to make a class variable and then use the this keyword to access it, for example this.name...
Last edited on
I'm not sure, but most likely this error caused when your compiler found that a duplicate variable name "name" is exist.

Can you post your full source class please?
Last edited on
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
// user.h
#ifndef USER_H
#define USER_H
#include <string>
#include <vector>
using namespace std;

struct userData {
	int id;
	string username;
	int birthyear;
	int zipcode;
	vector<int> friends;
};
class User {
	public:
		User(string name, int year, int zip, int &numusers);
	     ~User();
		void add_friend(int IDtoAdd);
		void delete_friend(int IDtoDelete);
		string return_name(int ID);
		int return_id(string name);
		int return_year(int ID);
		int return_zipcode(int ID);
};

#endif 
Ok I see.

char name = '0' + numusers;

userData *name = new userData;

Here, the error.
Sorry, I know that's what causes the problem, but I'm not sure how to fix it. Ben, what would I need to include in the struct for another class to use this? And Jackson, what exactly is wrong in those two lines?
char name


userData *name


"‘name’ has a previous declaration as ‘char name’"


Two "name" variables. Just change one.

For example :

char name;
userData *uName;
Last edited on
I know that part. The point is that I want to use the input variable (say it's 0 for the first call) and make an object name, in this case, '0'. I'm trying to come up with a way around this in case it just isn't possible
How do I use the input as a name?


I know that part. The point is that I want to use the input variable (say it's 0 for the first call) and make an object name, in this case, '0'. I'm trying to come up with a way around this in case it just isn't possible


I haven't understood what you are saying. You want to input User name and store the result into a variable through a function, right?
Last edited on
I want to call the constructor function, for example:
User("Mike", 1981, 90007, 0) // where there are 0 current users; Mike is the first

Then name the struct after the number user that Mike is (he'd be user number 0), so:
1
2
3
4
5
user0->id = 0;
user0->username = "Mike";
user0->birthyear = 1981;
user0->zipcode = 90007;
user0->friends // Empty vector until I add some integers 
Or when I call this constructor, say, from a testfile.cpp, would I just have to include
user0.User("Mike", 1981, 90007, 0) ?

Is this the right way to think of it?
Your code is perfect (??), and no need to say more.

But, you created
userData *name = new userData;

It's not a global variable.

Any your attempt will be destroyed when the class has finished its constructor function.
Try defining an userData variable in class header file then use it instead of a temporary variable.

Last edited on
I think I get the basic idea of what you are trying to do.

I think your view on the problem is a bit sideways.
Instead of trying to straighten out your model I shall pursue my own and ask if it is similar to what you are trying to build:

I setup a user struct, similar to your userData struct.

There is no User class! Each user is represented by his data (stored in an instance of user). I think this is where your primary confusion is.

In this model a users id is the address where his data is stored, although they can be referenced by number as well, as you will see below.

I store users in a vector (similar to an array).

Here is my code for a working model with a few initial features, like listing all users names, adding users to each others friends lists, displaying a list of everyone's friends, etc.
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
#include <iostream>
#include <vector>

using namespace std;

struct user {
//	int id;
	string name;
	int birthyear;
	int zipcode;
	vector<user*> friends;

	// functions
	user(string Name, int year, int zip)
	{
	    name = Name;
	    birthyear = year;
	    zipcode = zip;
	}
};

bool make_friends( user* p_u1, user* p_u2 )
{
    // add a check here to see if these two are already friends.
    // if so, return false here (don't add same friend twice)

    // OK - in the clear
    p_u1->friends.push_back( p_u2 );// u2 is now on u1's friend list
    p_u2->friends.push_back( p_u1 );// I assume that should be mutual

    return true;
}

void list_all_names( const vector<user*>& p_users )
{
    if( p_users.size() == 0 )
    {
        cout << " There are no users! " << endl;
        return;
    }

    cout << "The list of user names is:" << endl;
    for( unsigned i = 0; i < p_users.size(); ++i )
        cout << p_users[i]->name << endl;

    cout << endl;
    return;
}

bool list_friends( user* p_u )
{
    cout << p_u->name << "'s friends are: ";
    if( p_u->friends.size() == 0 )
    {
        cout << p_u->name << " has no friends! " << endl;
        return false;
    }

    for( unsigned i = 0; i < p_u->friends.size(); ++i)
        cout << p_u->friends[i]->name << " ";

    cout << endl;
    return true;
}

int main()
{
    vector<user*> Users;// a users id = his address in memory

    // add some users
    Users.push_back( new user("Joe", 1984, 91006) );
    Users.push_back( new user("Bob", 2001, 90678) );
    Users.push_back( new user("Sally", 1993, 41266) );
    Users.push_back( new user("Ann", 1945, 22314) );
    Users.push_back( new user("Frank", 1972, 43682) );

    // I'll list them for you now
    list_all_names( Users );

    // Lets make Joe, Sally and Frank all friends, shall we?
    make_friends( Users[0], Users[2] );// Joe and Sally make friends
    make_friends( Users[0], Users[4] );// Joe and Frank make friends
    make_friends( Users[2], Users[4] );// Sally and Frank make friends

    // Lets check that by listing everyones friends
    for( unsigned i = 0; i < Users.size(); ++i )
        list_friends( Users[i] );


    cout << endl;
    return 0;
}

Output:

The list of user names is:
Joe
Bob
Sally
Ann
Frank

Joe's friends are: Sally Frank
Bob's friends are: Bob has no friends!
Sally's friends are: Joe Frank
Ann's friends are: Ann has no friends!
Frank's friends are: Joe Sally


Is this the sort of thing you are thinking of?

The various functions called in main() could be made into function members of the user structure (or make it a class). Consider the global functions as an initial implementation method.

I hesitate to go further though since you may come back and say something like " What's all that? That's NOTHING like what I'm trying to build here! "

So, let me know.
This is actually spot on. I hadn't thought that the vector needed to be of pointers to instances of users. I'll work on it with this in mind and post back.

If I do make it a class, does there need to be both a struct and a class? Or would I just move all the fields of the user struct into the class?
Last edited on
I'm glad I got that about right.

You said:
I hadn't thought that the vector needed to be of pointers to instances of users.


It doesn't have to be, but I have reason for it.

In case you have never thought about this:
When you store objects in a vector directly, and then a push_back() operation causes a reallocation of storage space for the vector all existing objects are moved to new memory locations.

Problem: We are storing pointers to users in each users friends vector.
When the users move in memory, all pointers to them become invalid.
This is a disaster.

When pointers to objects are stored, the pointers themselves will be moved in memory on reallocation, but their values, ie. the addresses they point to, will remain unchanged. All pointers to users already handed out remain valid.

EDIT: I forgot to answer your question.

If I do make it a class, does there need to be both a struct and a class? Or would I just move all the fields of the user struct into the class?

There is no struct and some separate class! The user structure is it!
When I said you might make it a class I meant thet it could be changed from
struct user; to class user; instead.

I may post back with things developed this way a bit more, so you can see.

EDIT2:

OK. I have turned user into a class and have converted the make_friends() and list_friends() to member functions of the user class.
I also added friends for poor friendless Bob and Ann, so the output is a little different:

Note how the code for calling the functions in main() is different, since they are user class member functions now.
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
#include <iostream>
#include <vector>

using namespace std;

class user
{
    public:
//	int id;
	string name;
	int birthyear;
	int zipcode;
	vector<user*> friends;

	// functions
	bool make_friends( user* p_u );
	bool list_friends(void);

	// ctor
	user(string Name, int year, int zip): name(Name), birthyear(year), zipcode(zip) {}
};

bool user::make_friends( user* p_u )
{
    // add a check here to see if these two are already friends.
    // if so, return false here (don't add same friend twice)

    // OK - in the clear
    friends.push_back( p_u );// p_u is now on my friend list
    p_u->friends.push_back( this );// I assume that should be mutual

    return true;
}

bool user::list_friends(void)
{
    cout << name << "'s friends are: ";
    if( friends.size() == 0 )
    {
        cout << name << " has no friends! " << endl;
        return false;
    }

    for( unsigned i = 0; i < friends.size(); ++i)
        cout << friends[i]->name << " ";

    cout << endl;
    return true;
}
//** end of user class member function definitions ***

// We still have one global function
void list_all_names( const vector<user*>& p_users )
{
    if( p_users.size() == 0 )
    {
        cout << " There are no users! " << endl;
        return;
    }

    cout << "The list of user names is:" << endl;
    for( unsigned i = 0; i < p_users.size(); ++i )
        cout << p_users[i]->name << endl;

    cout << endl;
    return;
}

int main()
{
    vector<user*> Users;// a users id = his address in memory

    // add some users
    Users.push_back( new user("Joe",   1984, 91006) );// 0
    Users.push_back( new user("Bob",   2001, 90678) );// 1
    Users.push_back( new user("Sally", 1993, 41266) );// 2
    Users.push_back( new user("Ann",   1945, 22314) );// 3
    Users.push_back( new user("Frank", 1972, 43682) );// 4

    // I'll list them for you now
    list_all_names( Users );

    // Lets make Joe, Sally and Frank all friends, shall we?
    Users[0]->make_friends( Users[2] );// Joe makes friends with Sally
    Users[0]->make_friends( Users[4] );// Joe makes friends with Frank
    Users[2]->make_friends( Users[4] );// Sally makes friends with Frank

    // Poor Bob and Ann deserve at least onr friend. How about each other?
    Users[1]->make_friends( Users[3] );// Bob makes friends with Ann

    // Lets check that by listing everyones friends
    for( unsigned i = 0; i < Users.size(); ++i )
        Users[i]->list_friends();


    cout << endl;
    return 0;
}

Output:

The list of user names is:
Joe
Bob
Sally
Ann
Frank

Joe's friends are: Sally Frank
Bob's friends are: Ann
Sally's friends are: Joe Frank
Ann's friends are: Bob
Frank's friends are: Joe Sally


EDIT3: Sorry, I keep adding more stuff to this!
Add these two weird functions after line 50 in the above code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// a couple of special tools
struct userRank// defines what userA < userB means, so they can be ranked, sorted, etc,,,
{
    // user p_u1 goes before p_u2 on a ranking list if p_u1 has more friends
    bool operator()( const user* p_u1, const user* p_u2 )
    {
        return p_u2->friends.size() < p_u1->friends.size();
    }
};

// defines what ostream << user means ( so we can do: cout << Users[i]; and a custom description will appear )
ostream& operator<<( ostream& os, const user& ru )
{
    os << "Name: " << ru.name << '\n';
    os << "Birth year: " << ru.birthyear << '\n';
    os << "zipcode: " << ru.zipcode << '\n';
    os << "I have " << ru.friends.size() << " friends." << '\n';
    return os;
}

Then add this code to main() after line 93 and add
#include<algorithm> at the top:
1
2
3
4
5
6
7
8
9
10
11
12
13
// sort users by popularity
    userRank ur;
    sort( Users.begin(), Users.end(), ur );

    // Are those with the most friends listed first?
    cout << endl;
    for( unsigned i = 0; i < Users.size(); ++i )
        Users[i]->list_friends();

    // Listing everyones full user data
    cout << endl << "All data for our full user base:" << endl;
    for( unsigned i = 0; i < Users.size(); ++i )
        cout << *Users[i] << endl;

New output:

The list of user names is:
Joe
Bob
Sally
Ann
Frank

Joe's friends are: Sally Frank
Bob's friends are: Ann Frank
Sally's friends are: Joe Frank
Ann's friends are: Bob
Frank's friends are: Joe Sally Bob

Frank's friends are: Joe Sally Bob
Joe's friends are: Sally Frank
Bob's friends are: Ann Frank
Sally's friends are: Joe Frank
Ann's friends are: Bob

All data for our full user base:
Name: Frank
Birth year: 1972
zipcode: 43682
I have 3 friends.

Name: Joe
Birth year: 1984
zipcode: 91006
I have 2 friends.

Name: Bob
Birth year: 2001
zipcode: 90678
I have 2 friends.

Name: Sally
Birth year: 1993
zipcode: 41266
I have 2 friends.

Name: Ann
Birth year: 1945
zipcode: 22314
I have 1 friends.
Last edited on
Topic archived. No new replies allowed.