Sign in to follow this  
Sean_Seanston

Static Pointer in a class problem

Recommended Posts

I have a class with a static pointer variable for a Sprite. The Sprite contains SDL_Surface*'s and SDL_Rects. I use this code in the class in the header file:
	static Sprite* background;
This code in the .cpp:
Sprite* Menu::background = NULL;
And this code to initialize the Sprite:
	background->init("menu.png");
When I run it, I get an exception and a debug output with "expression cannot be evaluated" errors for every member of the Sprite object that init() is trying to access. It all works fine if I just use a Sprite instead of a Sprite* and maybe that would be the best thing to do in this situation anyway, but I thought for future use it'd be good to find out what was going wrong here. I know I haven't provided a lot of code but I assume it must be something very simple relating to the pointer not being constructed correctly when I use a pointer. I tried using the new operator just out of curiosity and that seemed to work fine but in this case that'd probably be a bad thing to use wouldn't it? I suppose I could just use delete on it in the class' destructor but I don't want to do something that might be real sloppy. And on a related note: When is it best to use a pointer to an object in another object instead of the object itself? When the object being pointed to is particularly complex?

Share this post


Link to post
Share on other sites
Why is the member static?

I can see three alternatives: either the Menu owns the Background (in which case it should be a member and the menu should destroy it) or the Background is shared by many menus (in which case it could be stored via boost::shared_ptr<> between them, passed via constructor) or it is drawn by the object which owns the Menu instances (in which case the Menu doesn't care whether there is a Background or not, and it is the containers job to draw them in the correct order.).

In my game, it is roughly the latter (the background is actually an instance of the game).

As for the cause of your problem, you are calling a member function on a NULL pointer, which is wrong. You can't have it by value (well, you shouldn't, even if it appears to work) because you cannot call SDL functions before SDL_Init(). You would need to use new to create the instance at run time, and delete (before SDL_Quit()) it when cleaning up.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sean_Seanston
I have a class with a static pointer variable for a Sprite. The Sprite contains SDL_Surface*'s and SDL_Rects.

I use this code in the class in the header file:

*** Source Snippet Removed ***

This code in the .cpp:

*** Source Snippet Removed ***

And this code to initialize the Sprite:

*** Source Snippet Removed ***

When I run it, I get an exception and a debug output with "expression cannot be evaluated" errors for every member of the Sprite object that init() is trying to access.

It all works fine if I just use a Sprite instead of a Sprite* and maybe that would be the best thing to do in this situation anyway, but I thought for future use it'd be good to find out what was going wrong here.

I know I haven't provided a lot of code but I assume it must be something very simple relating to the pointer not being constructed correctly when I use a pointer. I tried using the new operator just out of curiosity and that seemed to work fine but in this case that'd probably be a bad thing to use wouldn't it? I suppose I could just use delete on it in the class' destructor but I don't want to do something that might be real sloppy.

And on a related note: When is it best to use a pointer to an object in another object instead of the object itself? When the object being pointed to is particularly complex?
Based on your post and your code excerpts, it sounds like the Sprite object is never created (we'd need to see all your code to confirm that, however).

To complete your example, you would typically create the object via new at some point, e.g.:
backround = new Sprite;
And then delete it when you're done with it:
delete background;
However, it's probably worth taking another look at your design. Reasons for this include (but are not limited to):

1. Raw pointers require a lot of maintenance, and are somewhat error-prone (prefer RAII containers - such as smart pointers - instead).

2. Initialization should generally take place in the object's constructor, not in an 'initialization' function (reflecting the OOP ideal that objects be in a valid state from creation to destruction).

3. Prefer local and member data over global/static data (read any of the several recent threads on the subject for supporting arguments).

4. Only use pointers (this includes smart pointers) when you have a good reason for doing so (e.g. to support polymorphism or shared ownership).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this