I am trying to pass a member function within a class to a function that takes a member function class pointer. The problem I am having is that I am not sure how to properly do this within the class using the this pointer. Does anyone have suggestions?
Here is a copy of the class that is passing the member function:
class testMenu : public MenuScreen{
public:
bool draw;
MenuButton<testMenu> x;
testMenu():MenuScreen("testMenu"){
x.SetButton(100,100,TEXT("buttonNormal.png"),TEXT("buttonHover.png"),TEXT("buttonPressed.png"),100,40,&this->test2);
draw = false;
}
void test2(){
draw = true;
}
};
The function x.SetButton(...) is contained in another class, where "object" is a template.
void SetButton(int xPos, int yPos, LPCWSTR normalFilePath, LPCWSTR hoverFilePath, LPCWSTR pressedFilePath, int Width, int Height, void (object::*ButtonFunc)()) {
BUTTON::SetButton(xPos, yPos, normalFilePath, hoverFilePath, pressedFilePath, Width, Height);
this->ButtonFunc = &ButtonFunc;
}
If anyone has any advice on how I can properly send this function so that I can use it later.
Others have told you how to do it correctly. But I'm surprised no-one told you this code is actually dangerous:
Since ButtonFunc is a parameter, it will go out of scope when the function returns. You are taking its address. You will get a value of type
void (object::**ButtonFunc)()
(pointer to a pointer to a member function) and assign it to this->ButtonFunc. At the time you would try to use this->ButtonFunc you would try to access the storage of the (now not existing anymore) local parameter, and your program would probably crash.I agree with Commodore's solution. But you have to change his line to
since ButtonObj is a pointer to object.
To call a member function by pointer, you need two things: A pointer to the object and a pointer to the function. You need both in
MenuButton::SetButton()
Then you can invoke the function using both pointers:
Don't forget to pass the pointer to your object to
MenuButton::SetButton()
:I'd strongly recommend
boost::bind
andboost::function
for anything like this.See Pass and call a member function (boost::bind / boost::function?)
I know this is a quite old topic. But there is an elegant way to handle this with c++11
declare your function pointer like this
declare your the function your pass this thing into
suppose you pass a normal function to it you can use it like normal
suppose you have a member function
in your code you can pass it using
std::placeholders
like thisWould you not be better served to use standard OO. Define a contract (virtual class) and implement that in your own class, then just pass a reference to your own class and let the receiver call the contract function.
Using your example (I've renamed the 'test2' method to 'buttonAction'):
In the receiver method, you store the reference to a ButtonContract, then when you want to perform the button's action just call the 'buttonAction' method of that stored ButtonContract object.
In the rare case that you happen to be developing with Borland C++Builder and don't mind writing code specific to that development environment (that is, code that won't work with other C++ compilers), you can use the __closure keyword. I found a small article about C++Builder closures. They're intended primarily for use with Borland VCL.