passing pointer objects

Started by
6 comments, last by Code Fusion 17 years, 10 months ago
Alright, apparently I've lost my mind. I had no previous problems passing pointers, but now I'm having a mess of problems. I've tried all sorts of variations, some would build, but leave me with null pointers and thus a crashing program.. And now I'm looking for help, as I know I'm just missing something small.. Here's the code I think would be of the most importance:

//first we create our objects in winmain.cpp
D3D dev;
input inputs;
sound sounds;
Game game(&dev, &inputs, &sounds);

//now I'm showing the game file
public:
	int Game_Init(HWND);
	void Game_Run(HWND);
	void Game_End();
	Game(D3D *item, input *item2, sound *item3);
private:
	LPD3DXSPRITE sprite_handler;
	SPRITE asteroid;
	LPDIRECT3DTEXTURE9 asteroid_image;
	LPDIRECT3DSURFACE9 background;
	D3D *dev;
	input *inputs;
	sound *sounds;
	ui *UI;
	int gameState;
};

//This all worked fine.. Then I tried to build my UI, and problems arise.. The following is from game.cpp

UI = new ui(&dev, &inputs, &sounds, &sprite_handler);
UI->Init_UI();

//Now here's how I have things setup in the UI.h
class ui
{
public:
	ui(D3D *item, input *item2, sound *item3, LPD3DXSPRITE &item4);
	int Init_UI();
	void Run_UI(HWND);
	void End_UI();
private:
	LPDIRECT3DSURFACE9 background;
	LPDIRECT3DTEXTURE9 title_i;
	LPDIRECT3DTEXTURE9 newGame_i;
	LPDIRECT3DTEXTURE9 exit_i;
	LPDIRECT3DTEXTURE9 difficulty_i;
	LPDIRECT3DTEXTURE9 easy_i;
	LPDIRECT3DTEXTURE9 medium_i;
	LPDIRECT3DTEXTURE9 hard_i;
	LPDIRECT3DTEXTURE9 newGame_i_B;
	LPDIRECT3DTEXTURE9 exit_i_B;
	LPDIRECT3DTEXTURE9 difficulty_i_B;
	LPDIRECT3DTEXTURE9 easy_i_B;
	LPDIRECT3DTEXTURE9 medium_i_B;
	LPDIRECT3DTEXTURE9 hard_i_B;
	SPRITE title;
	SPRITE newGame;
	SPRITE exit;
	SPRITE difficulty;
	SPRITE easy;
	SPRITE medium;
	SPRITE hard;
	SPRITE itemArray[2];
	SPRITE itemArrayDiff[4];
	LPD3DXSPRITE sprite_handler;
	int menuScreen;
	D3D *dev;
	input *inputs;
	sound *sounds;
};

//and UI.cpp
ui::ui(D3D *item, input *item2, sound *item3, LPD3DXSPRITE &item4)
{
	dev = item;
	inputs = item2;
	sounds = item3;
	sprite_handler = item4;
}

Now I've tried a few variations, thinking I just had funky syntax. So I swapped some symbols just messing around, and it would tell me it's wrong. Basically every variation I tried I was told that it was wrong by the compiler. However, I can get it to compile if I pass the objects over from game.cpp without anything *s or &s.. But then I have empty copies of objects that cause my project to crash uncontrollably. Any ideas?
========================f4ntasmic Studiosf4nt's Blog========================
Advertisement
My first thought is that you're passing pointers to pointers where pointers are expected, and pointers where references are expected. Try changing this:
UI = new ui(&dev, &inputs, &sounds, &sprite_handler);
To this:
UI = new ui(dev, inputs, sounds, sprite_handler);
And see what happens.
Looks like it needs to be this to me:

UI = new ui(&dev, &inputs, &sounds, sprite_handler);

(no ampersand before sprite_handler).
Based on the amount of code that I saw, I would strongly urge you to rethink your approach. You're asking objects to hold pointers to variables that are local to some function. If the object "lives" longer than the function, e.g. gets copied to a static container, global object or something like that somewhere, then at the end of the function the pointed-to thing disappears and attempts to use the object go kaboom. In your case you're probably "ok" since it looks like you're doing all of that in main (WinMain), but it's still a bad design idea because (a) it's more complicated than what you need, and (b) it 'ties' the object instance to a function.

Why not just include actual objects (D3D, input, sound; as opposed to pointers thereto) as members of the Game, and have the constructor set them up as needed? Then you can remove code from the main loop, avoid dealing with those pointer passings that you can't seem to get right (and actually get rid of the parameters entirely), avoid dealing with pointers within the actual object implementation, and avoid storing the actual pointers in memory. Why do you think you *need* the pointers? Because the UI object wants to refer to the same objects? Why not just give the UI a Game*? (and if that runs into problems, maybe you'll find that the *real* problem is a poor separation of class responsibilities.)

Also, you should be aware that DirectX types starting with 'LP' are *already* pointers.
Zahlman, you're right, I could move everything to the Game class, and remove a good chunk of code from WinMain. However, unless I'm missing something, then all I'm doing is exactly that, moving a chunk of code from winmain, over to my game class. Granted, then I'll just have to pass a Game pointer around, rather than the 4 pointers I'm moving around right now. This also would make my game class my focal point for starting everything, thus effectively making it winmain. My question is this, why not just let winmain be winmain? I don't completely disagree with your thoughts, but if we're talking about making my code prettier (as opposed to just fixing my current problem at hand) then there's about 100 different ways I could do that. For one, this isn't an excessively serious project, more of a hack job prototype, that I want to see working..

Reason being is that I could drastically change my approach after I test a few plans that I have in mind. If my plans that I have in mind don't work, then I have to rework a bunch of things anyway, and then we can talk about redesigning things. Until then, I'd rather not go through a bunch of redesigns, and I'd rather just get my somewhat sloppy code to work. That being said, I'm not bashing/flaming here, and I don't want it to come off that way. I really do appreciate the tips, and they're perfectly warranted tips.. Just not exactly what I'm looking for at the moment.

As far the other suggestions.. Jyk, your suggestion throws build errors at me, something about couldn't convert D3D.. blah blah blah..

EasilyConfused's idea, which I've tried before, does in fact work.. However, it throws an exception at the first call to sprite_handler->draw(...)

Any other hints?

edit: Some oddities that I've discovered.. When I was playing with EasilyConfused's idea, which compiles, but throws exceptions.. I decided to try just creating a sprite handler just for the UI class. The odd part is that I just get thrown exceptions anytime that sprite handler tries to do anything. Which would lead me to believe d3ddev == NULL, but its not. At least, the checks I've placed in the code haven't raised any flags to tell me otherwise.
========================f4ntasmic Studiosf4nt's Blog========================
The LPD3DXSPRITE type is defined as a pointer to the ID3DXSprite interface.
passing & LPD3DXSPRITE means that you passed the address of the pointer.
so basicly your error should be
"cannot convert from '* LPID3DXSprite' to 'LPID3DXSprite'"
so simply removing the address operator solves it.
you should use if (FAILED(createdevice)) to check if there were errs in intilizing the device.
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction."
im just beginning c++ and i could be wrong but...
UI = new ui(&dev, &inputs, &sounds, &sprite_handler);UI->Init_UI();


shouldn't this be:
UI* myUI = new ui(&dev, &inputs, &sounds, &sprite_handler);UI->Init_UI();


like i said im new to the language but from what ive learned so far you can only initialize dynamic memory to a pointer because the new operator returns an address in memory, not an actual type.

but then again i havent even learned classes or OOP yet so maybe thats an exception??
it's not an exception. she declared ui *UI; in the public section of the file (look at the begining).
notice that "ui" is the name of the class , while UI is the name of the instant. the acts as a bad
tactic for naming varaibles , cause they can be confused easily.
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction."

This topic is closed to new replies.

Advertisement