# function pointers

This topic is 5158 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Ok, new question in 10 minutes, I must be hitting a record. I have 2 classes, CGame and CNet. CNet has an instance in CGame. However, I have a method of CGame::NetMessageHandler, which I'd like to call from within CNet. What kind of a pointer do I need to create in CNet and how do I pass the address of the NetMessageHandler to it? I'll give it a try myself, but if anyone feels more comfortable with function pointers please help!

##### Share on other sites
class Foo{public:  int member_function(double);};Foo f;Foo* pf = &f;// Pointer to member functionint (Foo::*pmf)(double) = &Foo::member_function;int i = (f.*pmf)(1.5);    // call with objectint j = (pf->*pmf)(1.0);  // call with pointer to object

##### Share on other sites
If CNet has an instance of CGame why not just invoke the function NetMessageHandler using the dot operator?

// CNet instance of CGame
CGame foo;
foo.NetMessageHandler( );

##### Share on other sites
Quote:
 Original post by simbaIf CNet has an instance of CGame why not just invoke the function NetMessageHandler using the dot operator? // CNet instance of CGameCGame foo;foo.NetMessageHandler( );

I think you'll find that he said
Quote:
 CNet has an instance IN CGame

I dont think that you need function pointers as you can access the "parent" object.

These code fragments might help though

// headerclass CGame;class CNet{public:	CNet(CGame* pGame=NULL){ pGameObj=pGame;};	void SetGame(CGame* pGame){pGameObj=pGame;}	CGame* pGameObj;	void CallingFunction();};class CGame {public:	CGame()	CNet netItem;	void NetMessageHandler()	{          // other code	};};///////////////////////////////////// cpp for CGame...CGame::CGame() {    netItem.SetGame(this);}...////////////////////////////////////// cpp for void CNet::CallingFunction(){	//	assert(pGameObj!=NULL);        ...	pGameObj->NetMessageHandler();		...}

When the instance of CGame is created a "this" pointer is used to initialise the CNet object. After that accessing public members of CGame from CNet is easy.

Edited by Box2020

##### Share on other sites
Box2020 you were right that CNet is in CGame.
The problem is that I can't get CNet to see CGame. If I try
#include "CGame.h" a get some errors complaining it can't find some other classes. All header files are guarded by #ifndef's.
I'm almost there, but when I tried passing the method address, like:
CGame::CGame() {  m_cNet.GetGameMessageHandler(&NetMessageHandler);}

I could not, it gave an error of:
error C2276: '&' : illegal operation on bound member function expression.
Looking it up on MSDN it says that I'm trying to get the address of a virtual function. My function though is like this:
//headervoid NetMessageHandler(string cMessage_);//cppvoid CGame::NetMessageHandler(string cMessage_){	if (cMessage_ == "CONNECTED") {		m_cSounds[2].Play();	}}

Tried a lot of other stuff but still failed. Is there a way to do a cast or something to get it to work?

##### Share on other sites
Search in the forum for "member function pointer" and you will find a lot of answers.
But in your case I would solve the original problem. For me, the pointer solution looks like a dirty hack (if the copilation problem is the only reason for your choice).
And boost::Function would allow binding of any function (even bound members).

##### Share on other sites
Quote:
 CGame::CGame() { m_cNet.GetGameMessageHandler(&NetMessageHandler);}I could not, it gave an error of:error C2276: '&' : illegal operation on bound member function expression.

You cannot manipulate a bound member function, except by calling it. A bound member function is a member function that has already been associated (bound) with the object it is supposed to operate on (here, *this). What you need to pass around is a pointer to the unbound member function, which you get through &CGame::NetMessageHandler. Of course, you will also need to pass a pointer (or reference) to the appropriate CGame object you want that member function to be bound to (this).

Therefore, your code could look like

CGame::CGame() {  m_cNet.SetGameMessageHandler(&CGame::NetMessageHandler, this);}

with the SetMessageHandler function declared as void CNet::SetMessageHandler( void (CGame::*handler)(string), CGame* pobject);

And in your CNet code, you would bind the member function pointer and the object pointer together, as I have shown in my first post: (pobject->*handler)("hello");.

edit: Alternatively, as VolkerG points out, boost::function is an excellent solution.

##### Share on other sites
Ok - if I understand you correctly the problem is that you can't include CGame.h in the CNet header.

simple answer - DONT. use a forward declaration like this

//////////////////////////////// cnet.hclass CGame;class CNet{public:    CNet(CGame* pGame=NULL){ pGameObj=pGame;};    void SetGame(CGame* pGame){pGameObj=pGame;}    CGame* pGameObj;    void CallingFunction();};

then include the CGame header within the CNet.cpp
////////////////////////////////// cnet.cpp#include "stdafx.h"#include "cgame.h"void CNet::CallingFunction(){    pGameObj->NetMessageHandler();}

cgame.h should have the cnet header
///////////////////////////////// cgame.h#include "cnet.h"class CGame {public:    CGame();    CNet netItem;    void NetMessageHandler()    {    };};

and finaly the code for cgame
//////////////////////////////////// cpp for CGame#include "stdafx.h"#include "cgame.h"CGame::CGame() {    netItem.SetGame(this);}

this appears to move the header dependancies around but should get you there

##### Share on other sites
Going to search right now. I need to redeclare something that maybe wasn't clear in my above posts. I can't use CGame in CNet.
CGame is the main game class and #include's CNet. So when your telling me to write CNet::GetGameMessageHandler(..., CGame *obj) I can't. If I don't include "CGame.h" naturally it doesn't see CGame and complains about unknown type. If I include it I get unknown types in other classes in CGame.h. I'm quite tired as well, but that's besides the point!

##### Share on other sites
Quote:
 Original post by moucardSo when your telling me to write CNet::GetGameMessageHandler(..., CGame *obj) I can't. If I don't include "CGame.h" naturally it doesn't see CGame and complains about unknown type.

You don't need to have access to the full definition of CGame (which you have in CGame.h) to be allowed to declare functions taking CGame as a parameter (or returning CGame), nor do you need it for pointers to CGame. The full definition is required to know the size of CGame, but those things do not need that piece of information.

Therefore, your CNet.h header file can make do with a CGame class declaration instead of an actual definition:
class CGame;class CNet{  /* stuff */  void GetGameMessageHandler( void (CGame::*handler)(string), CGame *obj);  /* more stuff */};

On the other hand, the code for the functions that do use CGame (in CNet.cpp) will need to know how CGame is put together, and will require the CGame header file. However, at that point, you already have completed the CNet definition, and all goes well.

#include "CNet.h"  // CNet doesn't really need CGame.h #include "CGame.h" // CGame does need CNet.h for its CNet membervoid CNet::GetGameMessageHandler( void (CGame::*handler)(string), CGame *obj){  /* stuff */};

1. 1
2. 2
JoeJ
20
3. 3
4. 4
5. 5
frob
13

• 9
• 10
• 13
• 9
• 23
• ### Forum Statistics

• Total Topics
632195
• Total Posts
3004712

×