Need help with errors

Hi everyone I have an error that I cant figure out. I have searched and looked through my code and just can't figure out what is wrong. I am simply trying to create an object of an class in another class and I keep getting these errors.
I have been learning C++ off and on mainly as a hobby for 2 years any help will be apriciated.

titlescreen.h(16): error C2146: syntax error : missing ';' before identifier 'menu'

titlescreen.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

This is part of my titleScreen.h where I create the object and get the error on line 14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once


#include "InputManager.h"
#include <allegro5\allegro_font.h>
#include <allegro5\allegro_ttf.h>
#include "MenuManager.h"

class TitleScreen : public GameScreen
{
private:
	ALLEGRO_FONT *font;

	MenuManager menu;


This is MenuManager.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
#pragma once

#include "ScreenManager.h"
#include <vector>
#include "Animation.h"
#include "FadeAnimation.h"
#include "FileManager.h"
#include <sstream>
#include <string>

class MenuManager
{
private:
	std::vector<std::string> menuItems;
	std::vector<ALLEGRO_BITMAP*> menuImages;

	std::vector<std::vector<Animation*> > animation;

	int itemNumber;

	FileManager fileManager;

	std::vector<std::vector<std::string> > attributes;
	std::vector<std::vector<std::string> > contents;

	std::vector<std::string> animationTypes;

	float position[2];
	int axis;
	std::string align;
	ALLEGRO_FONT *font;

	void SetMenuItems();
	void SetAnimations();

	std::vector<Animation*> tempAnimation;
public:
	MenuManager();
	~MenuManager();

	void LoadContent(std::string id);
	void UnloadContent();
	void Update(InputManager &input);
	void Draw(ALLEGRO_DISPLAY *display);
};


This is MenuManager.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
#include "MenuManager.h"


MenuManager::MenuManager()
{
}


MenuManager::~MenuManager()
{
}

void MenuManager::SetMenuItems()
{
	for(int i = 0; i < menuItems.size(); i++)
	{
		if(menuImages.size() ==  i)
			menuImages.push_back(NULL);
	}

	for(int i = 0; i < menuImages.size(); i ++)
	{
		if(menuItems.size() == i)
			menuItems.push_back("");
	}
}

void MenuManager::SetAnimations()
{
	float *pos = position;

	for(int i = 0; i < menuItems.size(); i++)
	{
		for(int j = 0; j < animationTypes.size(); j++)
		{
			if(animationTypes[j] == "Fade")
				tempAnimation.push_back(new FadeAnimation);
			tempAnimation[tempAnimation.size()-1]->LoadContent(menuImages[i],
				menuItems[i], position);
		}
		animation.push_back(tempAnimation);
		tempAnimation.clear();

		if(axis == 2)
			*(pos+1) += 30;
		else if(axis == 1)
			*(pos) += al_get_text_width(font,menuItems[i].c_str());
	}
}

void MenuManager::LoadContent(std::string id)
{
	fileManager.LoadContent("Load/Menus.txt", attributes, contents, id);

	for(int i = 0; i < attributes.size(); i++)
	{
		for(int j = 0; j < attributes[i].size(); j++)
		{
			if(attributes[i][j] == "Item")
				menuItems.push_back(contents[i][j]);
			else if(attributes[i][j] == "Image")
				menuImages.push_back(al_load_bitmap(contents[i][j].c_str()));
			else if(attributes[i][j] == "Font")
				font = al_load_font(contents[i][j].c_str(), 30, NULL);
			else if(attributes[i][j] == "Align")
				align = contents[i][j];
			else if(attributes[i][j] == "Animation")
				animationTypes.push_back(contents[i][j]);
			else if(attributes[i][j] == "Position")
			{
				std::stringstream str;
				str << contents[i][j];

				std::string value;

				int counter = 0;
				while(std::getline(str, value, ' '))
				{
					position[counter]  = atof(value.c_str());
					counter++;
				}
			}
		}
	}
	SetMenuItems();
	SetAnimations();
}

void MenuManager::UnloadContent()
{
	al_destroy_font(font);
	for(int i = 0; i < menuImages.size(); i++)
	{
		al_destroy_bitmap(menuImages[i]);
	}

	for(int i = 0; i < animation.size(); i++)
	{
		for(int j = 0; j < animation[i].size(); j++)
		{
			delete animation[i][j];
		}
	}
	animation.clear();
}

void MenuManager::Update(InputManager &input)
{
	for(int i = 0; i < animation.size(); i++)
	{
		for(int j = 0; j < animation[i].size(); j++)
		{
			if(itemNumber == i)
				animation[i][j]->SetIsActive(true);
			else
				animation[i][j]->SetIsActive(false);

			animation[i][j]->Update(input);
		}
	}
}

void MenuManager::Draw(ALLEGRO_DISPLAY *display)
{
	for(int i = 0; i < animation.size(); i++)
	{
		for(int j = 0; j < animation[i].size(); j++)
		{
			animation[i][j]->Draw(display);
		}
	}
}
Last edited on
where is the closing }; on line 14 ?
On which .cpp file compilation time it is giving error?

In that file you should include MenuManager.h before titlescreen.h
Last edited on
On which .cpp file compilation time it is giving error?

In that file you should include MenuManager.h before titlescreen.h

It can't be that - titleScreen.h already incoludes MenuManager.h.

I can't see any problems in the code you've posted. My guess would be that the problem is in one of the other header files included in MenuManager.h .

As a side-issue, I notice that MenuManager.h only uses pointers to Animation, ALLEGRO_BITMAP and ALLEGRO_FONT, so it doesn't actually need to include the header files defining those types. It doesn't need to know what those classes are, just that they are classes. You can get away with using forward declarations instead of including the definitions:

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

#include "ScreenManager.h"
#include <vector>
#include "FadeAnimation.h"
#include "FileManager.h"
#include <sstream>
#include <string>

// Forward declarations
class Animation;
class ALLEGRO_BITMAP;
class ALLEGRO_FONT;

class MenuManager
{
private:
	std::vector<std::string> menuItems;
	std::vector<ALLEGRO_BITMAP*> menuImages;

        // etc...
};

Last edited on
thanks for the replies

The closing }; is there , that is only part of the file.

The error is on line 14 of titleScreen.h

In what way would a header file in MenuManager.h cause a problem or what do I need to look for?

In what way would a header file in MenuManager.h cause a problem or what do I need to look for?

The error message seems to be saying that the compiler doesn't understand that MenuManager is the name of a type.

Since you clearly define MenuManager as a class in MenuManager.h, this suggests to me that there is some kind of syntax error that is causing that definition not to be properly understood.

I've had a look at the definition in MenuManager.h and I can see no problem with it. This suggests that the problem is in something else that is included in the code before the class definition. This means either one of the files that is included at the top of MenuManager.h, or else InputManager.h (which is included by titleScreen.h).

I would suggest looking for things like missing semicolons (particularly when closing a class definition - I always find those easy to forget), and missing close-braces.
Last edited on
Could it be something wrong with Visual C++ 2010 Express, If I try to create an object of menu manager in another class I get the same error and if I comment the code it compiles fine. Would it not show an error if I was missing a semi-colon?Could Circular Dependencies of header files cause these errors?
Last edited on
Could it be something wrong with Visual C++ 2010 Express

As a general rule, if you ever find yourself thinking "it could be a problem with my compiler", then you are almost certainly wrong. I'm paraphrasing that from something someone else posted here a few weeks ago, but it's true. Something like MSVC will have had more man-hours put into testing than you or I will ever spend coding in our entire lives. Unless you're making use of some obscure and advanced language feature that's not in the code you've posted - say, some new C++11 feature - the chance of it being a compiler bug is negligible.

If I try to create an object of menu manager in another class I get the same error and if I comment the code it compiles fine.

If you're creating a MenuManager object in another bit of code, then presumably you're also including MenuManager.h in that other code, which means that you're including the same other header files that MenuManager.h includes. So if there's an error in one of those files, you'll see it there too.

What exactly is it that you comment out to make it work?

Would it not show an error if I was missing a semi-colon?

C++ syntax is very flexible. You can nest statements inside other statements, nest code blocks inside code blocks, and generally come up with all sorts of ways to use the language that, when parsed by the compiler on a line-by-line basis, are legal in C++. The compiler might - totally legitimately - not know that you've missed a semicolon, or a close-brace, from any given line of your code. It's not the compiler's job to guess what you meant to do, only to check that each line of C++ is legal and if so to convert it to machine code.

Thus, it might be that the C++ you have written before line 16 of titleScreen.h - including the header files it includes - might be legal, but due to a mistake on your part, might not constitute a complete definition of the MenuManager type. This means that, until your code tries to actually use the MenuManger type on line 16 of titleScreen.h, the compiler thinks your code is legal. It's only at that point that the compiler says "Wait, what? I don't know yet what MenuManger is!" and reports an error.

In my experience, this is most likely to mean a missing semicolon, or that something is wrong with your braces. I've just looked over MenuManger.h and the fragment of titleScreen.h again, and still can't see anything wrong with them, so the problem must lie within some of the code that those files include that you haven't shown us.

Could Circular Dependencies of header files cause these errors?

It's possible, but in my experience that's more likely to result in error messages saying that there are multiple definitions of symbols.

In any case, since you're using #pragma once to protect against multiple inclusion in MenuManager.h, I'm assuming that you've already double-checked that you're doing it in all the header files included in MenuManager.h.
Last edited on
Thanks for the advice MikeyBoy.

What exactly is it that you comment out to make it work?

What I commented out was in TitleScreen.h where I created the object menu.
But I left the #include MenuManager.h header and it compiles fine. I dont know if that helps any I'll keep looking.

I have checked every .h for prama once
Well, that would be consistent with the idea that the code in MenuManager.h is legal C++, but does not constitute a complete definition of the MenuManager type. Once you comment out that line, then you're no longer attempting to use that type (assuming you don't try and use it elsewhere).

At this point, I think it would be quicker to just post the contents of those other header files.

Have you tried using the forward declaration I discussed earlier to remove the need to include Animation.h?

Also, do you need to include "FadeAnimation.h" in MenuManager.h? I can't see anything in MenuManger.h that uses a type called FadeAnimation.

If you don't need to include those two header files, then it would help narrow down the search for the file with the error.
Ok here is the other header files in MenuManager.h and I removed FadeAnimation.h and did a forward declaration of Animation. The headers included in MenuManager.h have there own includes do you need to see them also?

Animation.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
#pragma once

#include <allegro5\allegro.h>
#include <allegro5\allegro_image.h>
#include <allegro5\allegro_font.h>
#include <string>
#include "InputManager.h"

class Animation
{
public:
	Animation(void);
	~Animation(void);

	virtual void LoadContent(ALLEGRO_BITMAP *image,std::string text, float position[2]);
	virtual void UnloadContent();
	virtual void Update(InputManager input);
	void Draw(ALLEGRO_DISPLAY *display);

	virtual void SetAlpha(float value);
	float GetAlpha();

	void SetIsActive(bool value);
	bool GetIsActive();

protected:
	ALLEGRO_BITMAP *image, *sourceRect;
	std::string text;
	ALLEGRO_FONT *font;
	float position[2];
	float alpha;
	bool isActive;
};


FileManager.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
#pragma once

#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>
#include <algorithm>

class FileManager
{
private:
	enum LoadType { Attributes, Contents };
	int type;
	bool identifierFound;

	std::vector<std::string> tempAttributes;
	std::vector<std::string> tempContents;
public:
	FileManager();
	~FileManager();

	void LoadContent(const char *filename,std::vector<std::vector<std::string> > &attributes,
		std::vector<std::vector<std::string> > &contents);

	void LoadContent(const char *filename,std::vector<std::vector<std::string> > &attributes,
		std::vector<std::vector<std::string> > &contents, std::string identifier);
};



ScreenManager.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
#pragma once

#include <iostream>
#include <string>
#include "GameScreen.h"
#include "SplashScreen.h"
#include "TitleScreen.h"
#include "FadeAnimation.h"

//Allegro Inits
#include <allegro5\allegro.h>
#include <allegro5\allegro_image.h>

#define ScreenWidth 800
#define ScreenHeight 600

class ScreenManager
{
private:
	ScreenManager();
	ScreenManager(ScreenManager const&);
	void operator=(ScreenManager const&);

	//for testing
	std::string text;
	GameScreen *currentScreen, *newScreen;

	ALLEGRO_BITMAP *transitionImage;

	FadeAnimation transition;

	void Transition();

	bool startTransition;
public:
	~ScreenManager();
	static ScreenManager &GetInstance();

	void AddScreen(GameScreen *screen);

	void Initialize();
	void LoadContent();
	void UnloadContent();
	void Update(ALLEGRO_EVENT ev);
	void Draw(ALLEGRO_DISPLAY *display);
};



TitleScreen.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
#pragma once

#include "ScreenManager.h"
#include "InputManager.h"
#include <allegro5\allegro_font.h>
#include <allegro5\allegro_ttf.h>
#include "MenuManager.h"

class TitleScreen : public GameScreen
{
private:
	ALLEGRO_FONT *font;

	MenuManager menu;
public:
	TitleScreen();
	~TitleScreen();

	void LoadContent();
	void UnloadContent();
	void Update(ALLEGRO_EVENT ev);
	void Draw(ALLEGRO_DISPLAY *display);
};

I'm afraid I still can't see a problem with any of the code you've posted.

I would encourage you to continue to use the forward declaration idea I talked about earlier, to strip out as many unnecessary #include statements as possible. As a general rule:

If your file only uses pointers or references to a type, then it doesn't need to include the definition of that type - you can forward declare it instead.

If your file ever uses objects of a type, or derives from a type, or uses a member of a type, it needs to include the full definition.

So, for example, titleScreen.h needs the full definitions of MenuManager, GameScreen and ALLEGRO_EVENT, but doesn't need the full definitions of ALLEGRO_FONT or ALLEGRO_DISPLAY. (I don't see any need for it to include ScreenManager.h or InputManager.h, either.)

ScreenManager.h needs the full definitions of std::string, FadeAnimation and ALLEGRO_EVENT, but doesn't need the full definitions of GameScreen, ALLEGRO_BITMAP, or ALLEGRO_DISPLAY.

Etc, etc...

The more unnecessary #include statements you can remove, the more likely it is that you'll be able to narrow down the header files which might contain the problem. Also, it's generally a good idea to decouple your code as much as possible - as your project grows bigger, unnecessary dependencies can make the project take longer to compile than necessary, and require re-compilation more often than necessary.

Of course, you may then need to include those header files in the actual .cpp files that need them. But at least then, you're only including them where they're actually needed, rather than in a bunch of places where they're not.


Last edited on
Ok if I include MenuManager in TitleScreen.cpp and create an object everything works fine. Should I just start doing this for all my classes or is it considered bad code design.Here is the updated TitleScreen.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
#include "TitleScreen.h"
#include "MenuManager.h"

MenuManager menu;

TitleScreen::TitleScreen(void)
{
	
}

TitleScreen::~TitleScreen(void)
{
}

void TitleScreen::LoadContent()
{
	font = al_load_font("arial.ttf", 30, NULL);
	menu.LoadContent("Title");
}

void TitleScreen::UnloadContent()
{
	al_destroy_font(font);
	menu.UnloadContent();
}

void TitleScreen::Update(ALLEGRO_EVENT ev)
{
	if(input.IsKeyPressed(ev, ALLEGRO_KEY_ENTER))
		ScreenManager::GetInstance().AddScreen(new SplashScreen);
	menu.Update(input);
}

void TitleScreen::Draw(ALLEGRO_DISPLAY *display)
{
	//al_draw_text(font,al_map_rgb(255,0,0),100,100,NULL,"TitleScreen");
	menu.Draw(display);
}
Think I figured out the problem ,well I guess I did it works now.
I had ScreenManger.h included in both menuManager.h and titlescreen.h.
I don't really understand but I removed the screenmanager include from menuManager and it works.
Well, if ScreenManager.h has multiple inclusion protection (for which you seem to be using #pragma once , although I tend to do it the old-fashioned way), then that shouldn't be an issue. It still sounds like there's some sort of error hidden away in one of your header files.

Why does titleScreen.h need to include ScreenManger.h at all? What is it using from ScreenManager.h?
Last edited on
On line 30 of TitleScreen above I use ScreenManager::GetInstance(). I don't really know what is wrong because first I removed ScreenManger from TitleScreen.h and it still did not work.Then I removed it from MenuManager.h and included it in TitleScreen.h and it worked fine. I thought if I had ScreenManager.h included in MenuManager.h and then included MenuManager.h in TitleScreen.h it would include ScreenManager.h also.
On line 30 of TitleScreen above I use ScreenManager::GetInstance().

Which means that TitleScreen.cpp needs to include ScreenManager.h. But I don't see any reason why TitleScreen.h needs to include ScreenManager.h. Similarly, I don't see any reason why TitleScreen.h needs to include InputManager.h.

In general, you should only include header files in the files where they are needed, for the reasons I outlined in a previous post.

I don't really know what is wrong because first I removed ScreenManger from TitleScreen.h and it still did not work.Then I removed it from MenuManager.h and included it in TitleScreen.h and it worked fine. I thought if I had ScreenManager.h included in MenuManager.h and then included MenuManager.h in TitleScreen.h it would include ScreenManager.h also.

If A.cpp includes B.h, and B.h includes C.h, then A.cpp also includes C.h. So, yes, as you say, TitleScreen.h should include ScreenManager.h as you describe.
Thanks for all the help MikeyBoy. So you are saying include headers in cpp files if that is where you use it.I have always thought that you included what you need for the cpp file in the header for the cpp. I really don't get what is going wrong,but I have only been studying c++ off and on for 2 years so I still have alot to learn.
Yes, I'm saying that you include header files only where you need them. If the contents of a A.h require the inclusion of B.h - because it needs a type definition, say - then by all means include B.h.

But if you're only putting it in because another file that needs A.h also needs B.h, then don't do it. It may seem like a convenience, but in the long run, it's not. You've unnecessarily coupled your files, introducing a dependency that has no need to be there.

And remember that just having a pointer or reference to type B doesn't mean you need to include B.h. You can use a forward declaration instead.

Topic archived. No new replies allowed.