Static Pointer in a class problem

Started by
1 comment, last by Zakwayda 16 years, 2 months ago
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?
Advertisement
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.
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).

This topic is closed to new replies.

Advertisement