SDL2 sprite class issues.

I'm trying to create a sprite class that loads and draws sprites. I'm getting the following errors.

1
2
3
syntax error: missing ';' before '*'
missing type specifier - int assumed. Note: C++ does not support default-int
unexpected token(s) preceding ';'


I cannot for the life of me figure out why this will not compile. It all points to the "gameMain* gameGraphics" line under the private section of the gameSprite class. I'll post the code on pastebin because it may be too long for codeblocks here.

gameSprite.h (where error is): http://pastebin.com/4H2bi9nT
gameSprite.cpp: http://pastebin.com/jT3gNZq8
gameMain.h: http://pastebin.com/WcKqVN5B
gameMain.cpp: http://pastebin.com/H07ZGsEK

Everything was working fine until I attempted to add the gameSprite class. Now it won't compile. he gameMain class was working just fine and doing it's job of creating a window, processing input, etc, etc.
Any suggestions or tips would be greatly appreciated.


TLDR: Somewhere between sharing objects between gameSprite and gameMain there is something not working and I cannot figure out what it is.
Last edited on
gameMain.h includes gameSprite.h and gameSprite.h includes gameMain.h. You need to get rid of this circular dependency.

There is no need for gameMain.h to include gameSprite.h. Removing this include will probably fix your problem.

There is also no need for gameSprite.h to include gameMain.h but it's not enough to just remove the include. The class contains a pointer to a gameMain object so the compiler needs to know that there exist such a class before it's mentioned in the code. You can do that by using a forward declaration.

1
2
#include "gameMain.h"
class gameMain; // tells the compiler that there exist a class named gameMain 

If you do this change you will have to include gameMain.h in gameSprite.cpp in order to be able to use the class (create objects, call member functions, etc.).
Last edited on
Alright but now I cannot create an object of type gameSprite inside of gameMain.
If you want to do that you'll just have to include gameSprite.h in gameMain.cpp.
Well now my code is backwards and I'm completely lost :(

I still cannot create type gameSprite in the private section of gameMain.h without all the same similar errors.
Last edited on
If you want gameMain to have members of type gameSprite you need the full class definition of gameSprite, so in that case you should include gameSprite.h.
Last edited on
Currently
gameSprite.cpp includes gameSprite.h and gameMain.h
gameMain.cpp includes gameSprite.h and gameMain.h
gameSprite.h includes gameMain.h
To avoid circular dependencies you should prefer forward declarations and only use #include if it's necessary for that file to compile. Note that header files should be self-contained, meaning you should be able to compile a header file on its own without getting any errors .

A forward declaration is enough if all you have is a pointer (or reference) to the object. It's also enough if you declare (without defining) a function that uses the class as return type or as a parameter type.

1
2
3
4
5
6
7
8
9
class A;

class B
{
public:
	A foo(A a); // OK! Functions declaration containing incomplete type A is fine.
private:
	A* ptr; // OK! Pointer to incomplete type A is fine.
};


A forward declaration is not enough if the class contains actual objects (not pointers) of the class, or when defining a function that uses the class as return type or as function parameter type.

1
2
3
4
5
6
7
8
9
10
11
12
13
class A;

class B
{
public:
	A foo(A a) // Error! Function definition contains incomplete type A.
	{
		a.foo(); // Error! Can't call member function of incomplete type A.
		return a;
	}
private:
	A ptr; // Error! Member variable of incomplete type A.
};
To make this code compile the header that defines A should have been included instead of using a forward declaration.
Last edited on
Think I'll have to take a different approach for this then. I've understood classes and have used them before, but this is baffling me. Think I'll stick everything into one file and forgets classes for now. No matter what I do and combination of things I try. I cannot get it to work correctly.
Hi,

gameSprite.cpp includes gameSprite.h and gameMain.h
gameMain.cpp includes gameSprite.h and gameMain.h
gameSprite.h includes gameMain.h


that made me dizzy.
Peter87 said
You need to get rid of this circular dependency.
and I agree. Whatever you need for your gameSprite should be passed from your gameMain. Not having access directly to gameMain (in gameSprite) is a good thing
Think I'll have to take a different approach for this then. I've understood classes and have used them before, but this is baffling me. Think I'll stick everything into one file and forgets classes for now.

You don't need to do that. Start with your header files and make them compile. When that is working move on to your source files and add includes if necessary.

No matter what I do and combination of things I try. I cannot get it to work correctly.

I haven't seen your updated code so I can't say for sure what is wrong, but if all you have done is adding a few member variables of type gameSprite to gameMain, then it should be enough to put #include "gameSprite.h" back into gameMain.h and then do what I said about removing #include "gameMain.h" from gameSprite.h.
Last edited on
Seems I've gotten rid of the circular dependency but things just don't seem to work.

adding

 
gameSprite player;


will not compile when added to the private variables of gameMain.h. It seems to accept it and not show any errors (using VS, no red underlines, etc, etc), but when compiling I get a lot of the same errors I had.
Last edited on
Are the private variables pointers or actual objects of type gameSprite?

If they are pointers to objects of type gameSprite it should work (EDIT: I forgot to mention that you also need a forward declaration class gameSprite; in gameMain.h). Just remember to include gameSprite in gameMain.cpp.

If they are objects of type gameSprite you need to include gameSprite.h (#include "gameSprite.h" ) in gameMain.h. For this to not create a circular dependency it is important that you do what I described in my first post about removing #include "gameMain.h" from gameSprite.h.

I wrote:
There is also no need for gameSprite.h to include gameMain.h but it's not enough to just remove the include. The class contains a pointer to a gameMain object so the compiler needs to know that there exist such a class before it's mentioned in the code. You can do that by using a forward declaration.

1
2
#include "gameMain.h"
class gameMain; // tells the compiler that there exist a class named gameMain  

If you do this change you will have to include gameMain.h in gameSprite.cpp in order to be able to use the class (create objects, call member functions, etc.).
Last edited on
here is updated code. gameSprite* player is inside the private section of gameMain.h and will not compile.

gameMain.h: http://pastebin.com/0YtuLY49
gameMain.cpp: http://pastebin.com/hM40p7tW

gameSprite.h: http://pastebin.com/CC7h2QEL
gameSprite.cpp: http://pastebin.com/BrM6ZLpD

if I add gameSprite.h to gameMain.h and then remove gameMain.h from gameSprite.h I cannot create the gameMain object like I'm doing. This is why I'm confused. It seems I need to include them both in both locations to create an object of each, but then this creates a circular dependency.

Everything is going to need access to a gameMain object eventually to get things like the renderer, event, etc, etc.
Last edited on
gameMain.h is missing a forward declaration of class gameSprite. When the compiler sees player being defined on line 30 it doesn't know what gameSprite is so it gives you an error.

 
class gameSprite;
Last edited on
Alright. That seems to have been it. I can create the gameSprite object now and access it. Getting a nullptr error when using the loadSprite() function pointing to tempSurface but I guess that's a completely different problem.
Getting a nullptr error when using the loadSprite()

This is how I do mine:
terrianRender = SDL_LoadBMP( "Images\\plains2.bmp");
As long as you keep what ever you are trying to load in the working directory it's fine.

It's nice because if you ever have to share your code whomever is looking at it won't have to go and redefine filepath
Last edited on
naturally that would work but this is a function that loads a texture so it wont always be plains2.bmp. If you look at my code it is SDL_LoadTexture(filePath.c_str());
naturally that would work but this is a function that loads a texture


terrain = SDL_CreateTextureFromSurface(gRender, terrianRender);

It's now a texture
Topic archived. No new replies allowed.