"Error C2228: left of '' must have class/struct/union", about fifteen times?

Oct 16, 2011 at 12:41am
This is an expanded class example simulating a simple school course registration / display program. I'm getting the error C2228: left of '' must have class/struct/union all over the place within two .cpp files. I'm not entirely sure what NOT to include, so I'll give you the accompanying .h files as well. (I've also got some stuff commented out that's producing other errors... I made the mistake of not test compiling as I was going. If you see stuff wrong in other areas, I'd be happy to know.) My education in C++ is still fairly basic, but I'm getting there :P.

I've done a bunch of searching Google and the like, but nothing seems to address my problem, at least that I'm familiar enough to recognize. Any help would be greatly appreciated.

I'm using Visual Studio 2010 (full version).

User.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#pragma once
// #include "GlobalData.h"
#include "Course.h"
#include <iostream>
#include <string>
#include <vector>

class Course;

class User
{
public:
	std::string name;
	std::string id;
	std::string pw;
	int permission;
	std::vector<Course> courseList;

	User::User();
	User::User(std::string name, std::string id, std::string pw);
	// void User::DropCourse(int courseid);
	// void User::AddCourse(Course course);
	// void User::ShowCourseList();
};


User.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
#include "User.h"

User::User()
{
	User::User.name = "";
	User::User.id = "";
	User::User.pw = "";
}

User::User(std::string n, std::string i, std::string p)
{
	User::User.name = n;
	User::User.id = i;
	User::User.pw = p;
}
/*void User::DropCourse(int courseid)
{
	GlobalData function;
	int index = 0;
	index = function.FindCourse(User::courseList, courseid);
	if (index >= 0){
		User::courseList.erase(User::courseList.begin() + index);
	} else if (index < 0)
	{
		std::cout << "Course not listed." << std::endl;
	}
}
void User::AddCourse(Course course)
{
	User::courseList.push_back(course);
}
void User::ShowCourseList()
{
	for(int i = 0; i < User::courseList.size(); i++)
	{
		std::cout << User::courseList[i].courseid << std::endl;
		std::cout << User::courseList[i].name << std::endl;
		std::cout << std::endl;
	}
}*/


Course.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once

#include "User.h"
#include <iostream>
#include <string>
#include <vector>

class User;

class Course
{
public:
	User* instructor;
	std::string name;
	int courseid;
	std::vector<User> roster;

	Course::Course(std::string name, int courseid);
	Course::Course(User instructor, std::string name, int courseid);
	Course::Course(User instructor, std::string name, int courseid, std::vector<User> roster);
};


Course.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "Course.h"

Course::Course(std::string n, int c)
{
	Course::Course.name = n;
	Course::Course.courseid = c;
}
Course::Course(User i, std::string n, int c)
{
	Course::Course.name = n;
	Course::Course.courseid = c;
	Course::Course.instructor = i;
}
Course::Course(User i, std::string n, int c, std::vector<User> r)
{
	Course::Course.name = n;
	Course::Course.courseid = c;
	Course::Course.instructor = i;
	Course::Course.roster = r;
}


(I'm also getting the red squiggly under the i in the above Course::Course.instructor = i;, which placing a & before doesn't seem to solve.)

Now, the output dialog:

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
1
1>Build started 10/15/2011 5:12:34 PM.
1>InitializeBuildStatus:
1>  Touching "Debug\Webasvisor 3.0.unsuccessfulbuild".
1>ClCompile:
1>  User.cpp
1>g:\webasvisor 3.0\webasvisor 3.0\user.cpp(5): error C2228: left of '.name' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\user.cpp(6): error C2228: left of '.id' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\user.cpp(7): error C2228: left of '.pw' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\user.cpp(12): error C2228: left of '.name' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\user.cpp(13): error C2228: left of '.id' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\user.cpp(14): error C2228: left of '.pw' must have class/struct/union
1>  Course.cpp
1>g:\webasvisor 3.0\webasvisor 3.0\course.cpp(5): error C2228: left of '.name' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\course.cpp(6): error C2228: left of '.courseid' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\course.cpp(10): error C2228: left of '.name' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\course.cpp(11): error C2228: left of '.courseid' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\course.cpp(12): error C2228: left of '.instructor' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\course.cpp(16): error C2228: left of '.name' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\course.cpp(17): error C2228: left of '.courseid' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\course.cpp(18): error C2228: left of '.instructor' must have class/struct/union
1>g:\webasvisor 3.0\webasvisor 3.0\course.cpp(19): error C2228: left of '.roster' must have class/struct/union
1>  Generating Code...
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:01.12
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Last edited on Oct 16, 2011 at 12:50am
Oct 16, 2011 at 3:28am
1>  User.cpp
1>g:\webasvisor 3.0\webasvisor 3.0\user.cpp(5): error C2228: left of '.name' must have class/struct/union


In User.cpp on line 3 User::User, the scope resolution operator places you inside the User class scope and so from there on to the end of the function class members are accessed directly without the scope resolution operator. Change line 5:

User::User.name = "";

to

name = "";

What about the compiler's error message that
left of '.name' must have class/struct/union
? There actually is implicitly a class to the left of .name, the this pointer which points to the object being instantiated. That is, writing:

name = ""; is the equivalent of this->name = ""; which in turn is equivalent to ( *this ).name;. Still, you shouldn't use the this pointer in this case since it is already there implicitly.


The other errors appear to be similar.

Also, in User.h in lines 19 and 20 the first User in each line is redundant because you are already within the User class scope. Change lines 19 and 20 to:

1
2
	User();
	User(std::string name, std::string id, std::string pw);


It is in the source file User.cpp that you need to use the scope resolution operator and fully qualify the names of member functions because they are being implemented outside of the class.

Last edited on Oct 16, 2011 at 3:31am
Oct 16, 2011 at 4:30am
Wow, I had no idea. My instructor has been attempting to teach us the most "verbose" way to program, so I didn't think to rely on the implied.

Thanks very much!
Topic archived. No new replies allowed.