More info, Function Pointers

Started by
18 comments, last by GameDev.net 19 years, 9 months ago
Quote:Original post by psyjax
My linked lists are stored using the STL List template, so it shouldn't be a problem with the whole pointer thing considering that the STL List takes pointers anyway. A porgrammer friend of mind suggested that I should be able to typecast my derived class into a linked list of the parent class.


You don't even need to explicitly typecast:

// given thisclass Sprite {};class MySprite : public Sprite {};// and thisstd::list<Sprite*> AllSprites;// this is perfectly valid code:AllSprites.push_back(new Sprite());AllSprites.push_back(new MySprite());


Just be careful you don't throw any pointers to temporary (or stack-based) sprite objects into the list (i.e. local Sprite variables) as you'll end up causing invalid access exceptions.

Regards,
Jeff
Advertisement
Well, I did it!

I succesfuly implimented my move procs using inheritance. But now I got another issue. The linked list that holds the sprite will not call the derived classes virtual move proc.

Here is some code:

class cSprite{    private:        //some data and crap...    public:        virtual void MoveProc( void ) {;}};class cSpriteLayer{    public:        std::list <cSprite> SpriteList;        void DrawLayer( void );};void cSpriteLayer::DrawLayer( void ){    list <cSprite> :: iterator cur_sprite;    for( cur_sprite = SpriteList.begin();          cur_sprite != SpriteList.end();          ++cur_sprite )    {        cur_sprite->MoveProc();        cur_sprite->Draw();    }}//- Somewhere else in the code....class cMan : public cSprite{    public:        void MoveProc( void )        {            SetX(GetX()+0.1f);            cout << "I'm Moving!" << endl;        }};main(){   //set up crap   cSpriteLayer TheLayer;   cSprite *spr = new cMan;   TheLayer.SpriteList.push_back(*spr);       gameLoop()    {         TheLayer.DrawLayer();    }}


Why wouldn't this work?

I can call the move proc code from the derived class elsewhere in my code, but it does not get called in the linked list. What else do I need to do?

Does anyone know?

Thanx a bunch in advance. I really apreciate you alls help.
SpriteList in cSpriteLayer has to be a list of cSprite*, not of cSprite. That's how the whole inheritance thing works. And then don't dereference the pointer when you're calling push_back().

When you do it the way you did, you push_back() a cMan object, not a cSprite pointer, so when it gets added to the list, it has to cast cMan down to a cSprite (which I didn't know you could even do). Since the list only contains cSprites, it's going to call the cSprite version of the method and not the cMan version.

Once they're pointers, inheritance can work its magic and it should all work out.

-Auron
Yes, I thought you had stated your list stored pointers, but your code sample shows cSprite objects.

Also, make sure you delete anything that you allocated at end of program. It's up to you whether this is the responsibility of the cSpriteLayer (i.e. in its destructor run through all pointers and delete) or whether the client of the cSpriteLayer (i.e. the thing that creates the sprites in the first place) deletes the objects.

But they need to be deleted! Just like if you malloc something you must free it.

Regards,
Jeff
Btw, what is this?

main(){   ...    gameLoop()    {         TheLayer.DrawLayer();    }}


This looks like invalid code to me, some local function within the main() function?

Regards,
Jeff
grrr

Thanks Auron, Im partly there.

I did your changes, but now it broke the itterator. Does the itterator have to be of cSprite* ?

I tried it both ways, but I cant seem to get it to work. Lots of garbled errors.

When I declare the itterator as a <cSprite> the compiler can't find the appropriate list functions, if it's the <cSprite*> the compiler cant find the appropriate sprite functions.

Any idea on this?

hey ryper,

The code above is hevely abreviated :)

I just left in the important bits. Don't worry about memory and all that, Im takeing care of it, I just put the code in Im having trouble with.

As far as gameLoop(), I just put that there in place of the convoluted while/event/etc. crap I have there in the ACTUAL code heheh..

Im programming on my linux box, next to my G4 laptop, so I couldn't copy paste at the time. So you could imagine the trouble typing it all out, on this darn tiny keyboard too! heheh
std::list<cSprite*> MySprites;for(std::list<cSprite*>::iterator it = MySprites.begin(); it != MySprites.end(); ++it) {   cSprite* ptr = *it;   ptr->draw();}


Iterators must match the container type. De-referencing an iterator produces the type that you inserted into the container.

I know, STL errors can be a bitch.

Regards,
Jeff
rypyr!

Yahoo! You fixed it.

Now I can go to bed with an easy spirit :D

Seriously, I hate going to bed with coding problems on the brain, drives me nuts. Toss and turn, wake up screeming things like "It's the pointer! It's the pointer!"

hehehe

Anyway, thanks a bunch.
btw, as to your original question, someone developed a really really cool way to make member function pointers and "normal" function pointers more compatible.

The article is fairly long but extremely informative, and at the end he wraps it up with his library for using delegates in an optimal way with a much simpler syntax than boost::bind.

Here's the address:
http://www.codeproject.com/cpp/FastDelegate.asp

This topic is closed to new replies.

Advertisement