Problem with creating an array of a custom class in another custom class

Hello everybody!

In an effort to better learn the workings of C++ and OpenGL, I've been creating a simple engine of sorts where I can make a (probably crappy) game.

Anyways, I'm getting to the point of reading in OBJ files and displaying them, etc. To represent these files, I've created a class called OBJModel. This class is specified inline with its header file. Here's some of the code below. I've only included the parts that I think are related to the problem...
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
// OBJModel.h

#pragma once
#pragma warning(disable:4305)

/* #defines go here */

#include <gl/gl.h>
#include <gl/glu.h>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

#include "Vector.h"
#include "Polygon.h"

class OBJModel
{  private:
      Vector* vertices;
      Polygon* polygons;

      /* other attributes here */

   public:
      OBJModel(void) { /* code removed */ }

      OBJModel(const char* filename) { /* code removed */ }

      ~OBJModel(void) { /* code removed */ }

      // reads the .obj file and populates the arrays...
      void loadFile(const char* filename) { /* code removed */ }

      /* other code not related to the problem left out */
};


Now, as you can see, this class makes use of 2 other classes: Vector and Polygon. Vector is used in many, many other places in this engine, and Polygon is only used for the OBJModel class.

Here are their header files as well. First up is Vector.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Vector.h

#pragma once
#pragma warning(disable:4305)

/* #defines go here */

#include <cmath>

// another non-related custom class
#include "Matrix.h"

class Vector
{  /* constructors, math related methods, get/set methods */  
};


Now, here's the Polygon.h file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Polygon.h

#pragma once
#pragma warning(disable:4305)

class Polygon
{  private:
      /* various attributes */
   public:
      // default constructor
      Polygon(void) {}

      // constructor with all attributes provided
      // (not specifically written out in this sample)
      Polygon(int i1, int i2, ...) { /* assigns given values to attributes */}

      ~Polygon(void) {}

      /* get and set methods */      
};



Now, in my code, I would like to be able to create on OBJModel object based on an .obj file. The code to do this is listed below.
1
2
3
4
5
...
#include "OBJModel.h"
...
OBJModel test = OBJModel("test.obj");
...


Now, when I attempt to compile the code, the compiler spits out the following errors, which correspond to line 21 in the file OBJModel.h (provided above)
1
2
3
error C2143: syntax error : missing ';' before '*'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

...which means that OBJModel does not like the Polygon class. However, the line just above it (for the Vector class) works just fine. These two files look very similar, as seen above, so I don't know why it is behaving like this.

I'm using Visual C++ 2008.
If there's not enough code to help solve the problem, just let me know, and I'll post more, but I think that the problem would be in the parts given. I've tried solving this problem for a while, and I'm making no progress, so I figure I'd put it up online in hopes that someone else knows what's going on. Knowing my luck, it's probably something very stupid on my part.

If there's any other info needed, I will be happy to provide it, just ask!

Does anyone know what's going on?
Thanks in advance!
...which means that OBJModel does not like the Polygon class. However, the line just above it (for the Vector class) works just fine. These two files look very similar, as seen above, so I don't know why it is behaving like this.


I've no idea how you came to this conclusion. The error that you specified could mean a lot of things. You need to create a small project and COPY AND PASTE the code into this thread exactly as you compiled it otherwise there is no way that anyone could figure out what that compiler error means. You could have typed something into this post correctly but there is a typo in what you are actually trying to compile.
I didn't mean for that line to sound like that. I was just noting that the compiler started getting confused around the Polygon class.
Sorry about that!

Anyways, I spent a while coming up with a small code sample that will reproduce the results.
I was able to do it with four files (which I have tried to compact as much as possible)

Sorry, but this will have to be spread out over at least 2 posts...

1) main.cpp -- handles win32 programming, it's only here to serve as an 'entry point'
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN

#include <windows.h>
#include "OBJModel.h"

bool exiting = false;
long windowWidth = 800;
long windowHeight = 600;
long windowBits = 32;
bool fullscreen = false;

HDC hDC;

void SetupPixelFormat(HDC hDC)
{	int pixelFormat;

	PIXELFORMATDESCRIPTOR pfd = {0};
    
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;

    pixelFormat = ChoosePixelFormat(hDC, &pfd);
    SetPixelFormat(hDC, pixelFormat, &pfd);
}

LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{	static HDC hDC;
    static HGLRC hRC;

	static POINT oldPos;
    int height, width;

    switch (uMsg)
    {	case WM_CREATE:
		
			hDC = GetDC(hWnd);
			SetupPixelFormat(hDC);
			hRC = wglCreateContext(hDC);
			wglMakeCurrent(hDC, hRC);
			break;

		case WM_DESTROY:
		case WM_QUIT:
		case WM_CLOSE:

			wglMakeCurrent(hDC, NULL);
			wglDeleteContext(hRC);

			PostQuitMessage(0);
			break;

		case WM_SIZE:
	        height = HIWORD(lParam);
			width = LOWORD(lParam);
			break;

		case WM_PAINT:
	        PAINTSTRUCT ps;
			BeginPaint(hWnd, &ps);
			EndPaint(hWnd, &ps);
			break;

		case WM_KEYDOWN:
			int fwKeys;
			LPARAM keyData;
			fwKeys = (int)wParam;    // virtual-key code 
			keyData = lParam;          // key data 
	
			switch(fwKeys)
			{	case VK_ESCAPE:
					PostQuitMessage(0);
					break;
				default:
					break;
			}
			break;

		default:
			break;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{	WNDCLASSEX windowClass;
    HWND       hwnd;
    MSG        msg;
    DWORD      dwExStyle;
    DWORD      dwStyle;
    RECT       windowRect;
	
    windowRect.left=(long)0; 
    windowRect.right=(long)windowWidth;
    windowRect.top=(long)0; 
    windowRect.bottom=(long)windowHeight;

    windowClass.cbSize          = sizeof(WNDCLASSEX);
    windowClass.style           = CS_HREDRAW | CS_VREDRAW;
    windowClass.lpfnWndProc     = MainWindowProc;
    windowClass.cbClsExtra      = 0;
    windowClass.cbWndExtra      = 0;
    windowClass.hInstance       = hInstance;
    windowClass.hIcon           = LoadIcon(NULL, IDI_APPLICATION);
    windowClass.hCursor         = LoadCursor(NULL, IDC_ARROW);
    windowClass.hbrBackground   = NULL;
    windowClass.lpszMenuName    = NULL;
    windowClass.lpszClassName   = TEXT("GLClass");
    windowClass.hIconSm         = LoadIcon(NULL, IDI_WINLOGO);

    if (!RegisterClassEx(&windowClass))
        return 0;

    if (fullscreen)	
    {	DEVMODE dmScreenSettings;
        memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
        dmScreenSettings.dmSize = sizeof(dmScreenSettings); 
        dmScreenSettings.dmPelsWidth = windowWidth;	
        dmScreenSettings.dmPelsHeight = windowHeight;
        dmScreenSettings.dmBitsPerPel = windowBits;


        dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

        if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
        {	MessageBox(NULL, TEXT("Display mode failed"), NULL, MB_OK);
            fullscreen = FALSE; 
        }
    }

    if (fullscreen) 
    {	dwExStyle=WS_EX_APPWINDOW;
        dwStyle=WS_POPUP;  
        ShowCursor(FALSE);
    }
    else
    {	dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        dwStyle=WS_OVERLAPPEDWINDOW;
    }

    AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);

    hwnd = CreateWindowEx(NULL,
						  TEXT("GLClass"),
						  TEXT("Test"), 
						  dwStyle | WS_CLIPCHILDREN |
						  WS_CLIPSIBLINGS,
						  0, 0, 
						  windowRect.right - windowRect.left,
						  windowRect.bottom - windowRect.top, 
						  NULL,                               
						  NULL,                               
						  hInstance,                          
						  NULL);                              

    hDC = GetDC(hwnd);

    if (!hwnd)
        return 0;

    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);

	SetCursorPos(windowWidth/2, windowHeight/2);
    
	DWORD EndTime = GetTickCount() + 100;
	int frame = 0;

    while (!exiting)
    {	SwapBuffers(hDC);

        while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {	if (!GetMessage(&msg, NULL, 0, 0))
            {	exiting = true;
                break;
            }

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
	
    if (fullscreen)
    {	ChangeDisplaySettings(NULL,0);
        ShowCursor(TRUE);
    }

    return (int)msg.wParam;
}


2) OBJModel.h -- the error is reported in this 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
#pragma once
// disable implicit float-double casting
#pragma warning(disable:4305)

#include <fstream>
#include <string>
#include <sstream>

#include "Vector.h"
#include "Polygon.h"

class OBJModel
{	private:
		Vector *vertices;
		Polygon *polygons;  //<----------------------------------------compiler complains about this line
		
		int numOfVertices;
		int numOfPolygons;

	public:
		OBJModel(void)
		{	numOfVertices = 0;
			numOfPolygons = 0;
		}

		OBJModel(const char* filename)
		{	numOfVertices = 0;
			numOfPolygons = 0;

			loadFile(filename);
		}

		~OBJModel(void)
		{	delete[] vertices;
			//delete[] polygons;
		}

		void loadFile(const char* filename)
		{	std::string line;
			std::string word;
			
			std::ifstream inputFile(filename);

			if (inputFile.is_open())
			{	while (!inputFile.eof())
				{	std::getline(inputFile, line);

					std::stringstream(line) >> word;

					if (word.compare("v") == 0)			numOfVertices++;
					else if (word.compare("f") == 0)	numOfPolygons++;
				}
			}
			inputFile.close();

			vertices = new Vector[numOfVertices];
			//polygons = new Polygon[numOfPolygons];
			
			int vertPos = 0;
			int polyPos = 0;

			std::ifstream inputFile2(filename);
			if (inputFile2.is_open())
			{	while (!inputFile2.eof())
				{	std::getline(inputFile2, line);

					std::stringstream lineStream2 = std::stringstream(line);
					lineStream2 >> word;

					if (word.compare("v") == 0)
					{	float x,y,z;
					
						lineStream2 >> x;
						lineStream2 >> y;
						lineStream2 >> z;

						vertices[vertPos] = Vector(x,y,z);
						vertPos++;
					}
					else if (word.compare("f") == 0)
					{	std::string info;
						std::string s1, s2;
						int location;

						int v1, v2, v3;
						int t1, t2, t3;
						int n1, n2, n3;

						lineStream2 >> info;

						location = info.find('/');
						s1 = info.substr(0, location);
						info.erase(0, location+1);

						location = info.find('/');
						s2 = info.substr(0, location);
						info.erase(0, location+1);

						std::stringstream(s1) >> v1;
						std::stringstream(s2) >> t1;
						std::stringstream(info) >> n1;

						v1--;
						t1--;
						n1--;


						lineStream2 >> info;

						location = info.find('/');
						s1 = info.substr(0, location);
						info.erase(0, location+1);

						location = info.find('/');
						s2 = info.substr(0, location);
						info.erase(0, location+1);

						std::stringstream(s1) >> v2;
						std::stringstream(s2) >> t2;
						std::stringstream(info) >> n2;

						v2--;
						t2--;
						n2--;


						lineStream2 >> info;

						location = info.find('/');
						s1 = info.substr(0, location);
						info.erase(0, location+1);

						location = info.find('/');
						s2 = info.substr(0, location);
						info.erase(0, location+1);

						std::stringstream(s1) >> v3;
						std::stringstream(s2) >> t3;
						std::stringstream(info) >> n3;

						v3--;
						t3--;
						n3--;

						//polygons[polyPos] = Polygon(v1, v2, v3, t1, t2, t3, n1, n2, n3);
						polyPos++;
					}
				}
			}
			inputFile2.close();
		}
};


3) Polygon.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
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
#pragma once
// disable implicit float-double casting
#pragma warning(disable:4305)

class Polygon
{	private:
		int v1;
		int v2;
		int v3;
		int t1;
		int t2;
		int t3;
		int n1;
		int n2;
		int n3;

	public:
		Polygon(void)
		{	v1 = v2 = v3 = t1 = t2 = t3 = n1 = n2 = n3 = 0;
		}

		Polygon(int vert1, int vert2, int vert3, int text1, int text2, int text3, int norm1, int norm2, int norm3)
		{	v1 = vert1;
			v2 = vert2;
			v3 = vert3;

			t1 = text1;
			t2 = text2;
			t3 = text3;

			n1 = norm1;
			n2 = norm2;
			n3 = norm3;
		}

		~Polygon(void) {}

		int getVertexIndex(int num)
		{	if (num == 1)		return v1;
			else if (num == 2)	return v2;
			else if (num == 3)	return v3;
			return -1;
		}

		int getTextureIndex(int num)
		{	if (num == 1)		return t1;
			else if (num == 2)	return t2;
			else if (num == 3)	return t3;
			return -1;
		}

		int getNormalIndex(int num)
		{	if (num == 1)		return n1;
			else if (num == 2)	return n2;
			else if (num == 3)	return n3;
			return -1;
		}		
};


4) Vector.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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#pragma once
// disable implicit float-double casting
#pragma warning(disable:4305)

class Vector
{	private:
				
	public:
		float x,y,z,w;
		
		Vector(void)
		{	x = 0.0f;
			y = 0.0f;
			z = 0.0f;
			w = 1.0f;
		}

		Vector(float X, float Y)
		{	x = X;
			y = Y;
			z = 0.0f;
			w = 1.0f;
		}

		Vector(float X, float Y, float Z)
		{	x = X;
			y = Y;
			z = Z;
			w = 1.0f;
		}

		Vector(float X, float Y, float Z, float W)
		{	x = X;
			y = Y;
			z = Z;
			w = W;
		}

		virtual ~Vector(void)
		{	
		}
};


Trying to compile a project with these 4 files gives the following errors:
1
2
3
objmodel.h(15) : error C2143 : syntax error : missing ';' before '*'
objmodel.h(15) : error C4430 : missing type specifier - int assumed. Note: C++ does not support default-int
objmodel.h(15) : error C4430 : missing type specifier - int assumed. Note: C++ does not support default-int


There can be more errors, but to keep down the numbers, I commented out the guilty lines of code in OBJModel.h.
If you want to see the rest, just uncomment those lines.

Thanks for the reply, and I hope this helps!
Well, I figured out the problem.
Turns out the header windows.h contains a method called Polygon, so that was causing the confusion. All I had to do was rename the Polygon class to something else, and it compiled fine.
...I'm dumb.

Anyways, if you do this 'fix' with the code I gave above, it won't compile, but for the actual project that I have, it works fine.

Thanks for the help though.
hehe you always wonder, when you see an intelligent sounding post describing such an issue: is it the poster who is "dumb", or is it the language that is wrong...
Last edited on
Topic archived. No new replies allowed.