Skip to main content
gamedev.net
🔒 Locked

some function pointer troubles

Started by DrZoidberg Mar 18, 2005 at 3:21 PM 8 replies 2.1k views
Original Post
DrZoidberg
DrZoidberg
ok i have a list of a struct which contains a function pointer to a member function. (it's for a basic gui system) struct XButton { // ... // ... void (IEventReceiver::*m_funcPtr)(void); }; ok during the update function of the gui system all buttons will be 'iterated' through and the ones pressed will execute whatever function their funcPtr points to. std::list::iterator i; // ... (*i)->m_funcPtr(); the last line will produce the error "error C2064: term does not evaluate to a function taking 0 arguments" (i'm using MS visual studio express '05) i just can't figure out why it is doing this. thanks for any help.
Woop woop woop woop!
doynax
doynax
Member function pointers are not automatically linked to any specific class instance, so just because you store them in one button doesn't mean you have to invoke them on the same instance.
XButton *p = *i;(p->*(p->m_funcPtr))();
DrZoidberg
DrZoidberg
Quote:

Member function pointers are not automatically linked to any specific class instance, so just because you store them in one button doesn't mean you have to invoke them on the same instance.


you lost me.

well before i call that function that the funcPtr points to, i am assigning it to the address of a function of a class that is of the type IEventReceiver.

anyways i tried the code and got this error ...

error C2440: 'newline' : cannot convert from 'CGooeySys::XButton *' to 'IEventReceiver *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Source\gooeySys.cpp(24) : error C2647: '->*' : cannot dereference a 'void (__thiscall IEventReceiver::* )(void)' on a 'CGooeySys::XButton *'

i guess i really don't know what it's talking about since i don't understand this.

(p->*(p->m_funcPtr))();

my brain hurts. what is this doing exactly?
Woop woop woop woop!
doynax
doynax
Oh, sorry. I just assumed that the button was an even receiver.
So what object do you want to call the member function on?

The difference between regular function pointers and member function pointers is, as the name implies, that you can call member functions through member function pointers.
When you normally call a member function you provide both an object instance and a member function to call, this is no different. Since the function pointer itself doesn't identify the instance you have to provide it manually somewhere.

Here's a short example illustrating the syntax of both.
class foo { static void bar1(); void bar2();}int main() { foo instance; void (*s_func)(); void (foo::*m_func)(); s_func = foo::bar1; m_func = foo::bar2; s_func();(instance->*m_func)(); return 0;}
DrZoidberg
DrZoidberg
i just realized what you mean ... i need an actual reference to an instance of the class which the function pointer class type is.

i think this would work then ...

struct XButton {
// ...
// ...
IEventReceiver *pEventReceiver;
void (IEventReceiver::*m_funcPtr)(void);
};

(pButton->pEventReceiver->*(pButton->m_funcPtr))();
Woop woop woop woop!
DrZoidberg
DrZoidberg
ahh crap, i think i've gotten myself into something that just isnt possible.

is this possible in any way ...

class A {
// ...
};

class B : public A {
public:
void foo(void);
}

void (A::*funcPtr)(void);

ok can i somehow pass the address of the function foo to funcPtr using reinterpret cast or something?

i've tried things like this (in my previous examples) ...

m_pGooey->createButton(blah, blah, reinterpret_cast(&DerviedClass::someFunction));

some way to do this? or time to redesign?
Woop woop woop woop!
DrZoidberg
DrZoidberg
ok i just figured it out ...

void (CDerived::*fp)(void);
fp = &CDerived::foo;

(void (IEventReceiver::*)(void))fp);
Woop woop woop woop!
snk_kid
snk_kid
Quote:
Original post by DrZoidberg
ahh crap, i think i've gotten myself into something that just isnt possible.

is this possible in any way ...

class A {
// ...
};

class B : public A {
public:
void foo(void);
}

void (A::*funcPtr)(void);

ok can i somehow pass the address of the function foo to funcPtr using reinterpret cast or something?

i've tried things like this (in my previous examples) ...

m_pGooey->createButton(blah, blah, reinterpret_cast(&DerviedClass::someFunction));

some way to do this? or time to redesign?


I think you don't yet quite understand pointer to member functions they are a completely different beast from pointer to functions.

Not only can you have an indirect calls but you can preform an indirect polymorphic calls, you cannot assign the address of (really its more like an offset) member function of a sub-type to a pointer to member function of some super-type.

How-ever you can assign the address of a (pure) virtual member function to a pointer to member function:

struct A {   virtual ~A() {};   virtual void do_bar() const = 0;};#include <iostream>struct B : A {   void do_bar() const {      std::cout << "B\n";   }};int main() {   typedef void (A::*mem_func)() const;   mem_func f = &A::do_bar;   B b;   const A& a_ref = b;   (b.*f)();		//regular indirect call   (a_ref.*f)();	//polymophic indirect call}


This should give you a clue and be ringing bells and you don't need to be casting you should design with interfaces.

A slight detour, i recommend you have look up on the observer design pattern for what your trying to do.
DrZoidberg
DrZoidberg
Quote:

A slight detour, i recommend you have look up on the observer design pattern for what your trying to do.


actually i have been using the observer pattern (well i think i am, i often start reading something, don't finish it, then try it myself ... somehow this time everything came together)

anyways the whole purpose of why im using function pointers is to do with a simple gui system.

like say i was creating a rts game and i wanted a unit to be able to attack and have a buttn that would invoke this. however i really don't want to worry myself about when the button is pressed or anything, i just want to create and forget about it.

struct ISomeInterface {

// Don't need anything here ... poor design ... yes

};

class CSoldierDude : public ISomeInterface {

private:

void doAttack(void) {
// Whatever
}

public:

CSoldierDude(CEngine *pEngine) {

pEngine->getGUI()->createButton(blah, blah, // pass doAttack with casting);

}

};

and then the button class would have a pointer to a member function of ISomeInterface ...

im sorta stuck on how i should be doing this without this horrible casting. any tips?

EDIT: i just don't understand how i can do this with interfaces, like what if CSoldierDude wanted 20 buttons ... then the interface would need 20 functions for each button and obviously not all classes would need this.
Woop woop woop woop!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.