I'm trying to code a Gameboy emulator and i would like to use a vector of function pointers to call the right function instead of doing a long switch statement.
For example if the program counter point to 0x00 (in memory), the first element of the vector is NOP so void NOP() is called;
but i can't figure how to call the functions.
Z80.h
#include <vector>
using namespace std;
class Z80;
typedef void (Z80::*function_t)();
class Z80
{
public:
vector<function_t> fmap;
...
...
};
Z80.cpp
Z80::Z80()
{
fmap = { &Z80::NOP, &Z80::LDBCnn, &Z80::LDBCmA};
}
void Z80::emulateCycle() {
opcode = memory.readByte(r.pc);
fmap[opcode](); <---ERROR
r.pc++;
}
void Z80::NOP() {
}
this is the error:
IntelliSense: expression preceding parentheses of apparent call must have (pointer-to-) function type
This expression:
fmap[opcode]
gives you a pointer to a member function. You can't just call that - it needs the class instance too. But you're actually calling it from a class method itself - so this is the instance you're looking for:
(this->*fmap[opcode])();
Note that if you want to avoid that bit of syntax and you're using C++11, you can change your fmap to instead be a vector of std::function<void()> and initialize it thusly:
fmap = { std::bind(&Z80::NOP, this), // or [this](){ this->NOP(); }
std::bind(&Z80::LDBCnn, this), // etc.
std::bind(&Z80::LDBCmA, this)};
That will let you actually do:
fmap[opcode]();
I'm not entirely sure that using function pointer in this case is particularly much better than for example a big switch statement.
However, the reason you can't call your member function is that you are not passing your object to the function.
You need this;
(this->*fmap[opcode])();
Another option is to use static/free function pointers, like this:
void (*function_t)(Z80& self);
and call it with:
fmap[opcode](this).
[Or use std::function and std::bind, which covers over the rather (intentionally, apparently) ugly syntax]
Related
I am having vector, that stores classes of type Sensor, which each have a member function refresh(). This vector is member of my class LogManager.
class Sensor
{
public:
void refresh();
}
class LogManager
{
private:
std::vector<Sensor*> sensors;
void refresh_sensors()
{
// TODO: use foreach
for (uint i=0; i<sensors.size(); i++)
{
sensors[i]->refresh();
}
for_each(sensors.begin(), sensors.end(), [sensors]( void* ) void* -> {refresh();} );
}
}
What I want to do is to change the for loop into the std::for_each() implementation. What you see above is my first try.
How can I access the member function Sensor::refresh() with the for_each() function?
Using a standard for loop like also above, I'd just use the -> operator.
Stretch goal is also to replace the std::vector<Sensor*> sensors; with a pointer: std::vector<Sensor*>* sensors; so that I do not have to work with copies. How would the implementation look in this case?
Hmm.
for_each(sensors.begin(), sensors.end(), []( Sensor * sensor ) void -> { sensor->refresh(); } );
I didn't try compiling it, so there might be a syntax problem. Things I changed:
You're not using the [sensors] section, so I emptied that.
If you're using void *, you're almost certainly doing something very un-C++-like. I changed it to the proper type.
You're not returning any value, so I changed the void * to void.
I don't actually use for_each. I personally think this code is far cleaner:
for (Sensor * sensor: sensors) {
sensor->refresh();
}
I think that's SIGNIFICANTLY easier to read. So doing it using for_each is a good practice problem, but I wouldn't have written it that way. Which also means I might have gotten the code slightly wrong.
You don't need to capture anything in the lambda in for_each. Instead, each pointer in the vector should be passed as an argument:
std::for_each(sensors.begin(), sensors.end(),
[](Sensor* s) { s->refresh();});
You don't need to (and shouldn't) make the vector a pointer, unless you want to pass it around without making copies. Since it's a private data member, that's probably not a good idea, and you can use references to do that anyway.
I'm new to c++ and I'm trying to make a generic switch (i.e. the device, not the C++ statement) that could be used to blink lights, turn beeps on and off, etc, in my Arduino project.
I could create a switchable interface and implement that in the classes that I want to "switch". But since I'm doing it as study purposes and I saw the pointer-to-functions ability in C++ (that is new to me since I come from C# and Java), I tough it would be a good opportunity to give it a try...
The problem is that I can pass the function in my code only if it's a local function but it won't work if I try to pass a function from another object like a led for example.
Some code to illustrate the problem. This is the switch.cpp, it recieves the On and Off functions in it's constructor and it has a update method that is called inside the loop method in the Arduino ino main class:
auto_switch.cpp
using switch_function = void(*)();
auto_switch::auto_switch(const switch_function on_function, const switch_function off_function, const int max_speed_count)
{
//sets all variables...
}
void auto_switch::update(const unsigned long millis)
{
//turn switch on and off...
}
And this is my ino file
ino file
#include <Arduino.h>
#include "led.h"
#include "auto_switch.h"
led* main_led;
auto_switch* led_switch;
int slow_speed;
//ugly code
void turn_led_on()
{
main_led->turn_on();
}
//ugly code
void turn_led_off()
{
main_led->turn_off();
}
void setup() {
main_led = new led(2, 3, 4, true, color::white);
//ugly code
led_switch = new auto_switch(turn_led_on, turn_led_off, 3);
slow_speed = led_switch->add_speed(100, 100, 3, 1000);
led_switch->set_active_speed(slow_speed);
led_switch->turn_on();
}
void loop() {
led_switch->update(millis());
}
It works but I had to make a local function (turn_led_on and turn_led_off) to be able to assign the inner functions as a parameter to the auto_switch constructor, the parts that I've wrote //ugly code
I wanted to do something like this, without the glue code in between:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
Is it possible? I've read something about static pointer to function and some std functions that help with that, if I get it right the glue code is necessary in this case so that the compiler can know where the functions are coming from I guess (from which object), but since the functions I need to call cannot be static I've discarded this option, and the std functions I believe it can't be used with the Arduino or could but shouldn't for performance limitations...
Anyway, does it make sense, can it be done using pointer to functions or should I create a interface or something different?
Before deciding how to do it, the qquestion is what do you want to do and why. Because, maybe there are better alternatives using simple C++ idioms.
Option 1: specialization with polymorphism
Do you want to specialize some functions of your switch, so instead of calling the function of the auto_switch you'd call dome more specialized ones ?
In this case you wouldn't do:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
but instead you would rely on polymorphism with virtual functions in the base class:
class auto_switch {
...
virtual void turn_on();
virtual void turn_off();
...
};
and write a specialized class for the leds:
class led_witch : public auto_switch {
...
void turn_on() override;
void turn_off() override;
...
};
In fact, the compiler will generate some function pointers behind the scene, but you don't have to care:
auto_switch s1=new auto_switch(...);
auto_switch s2=new led_switch(...); // no problem !!
s1->turn_on(); // calls auto_switch::turn_on()
s2->turn_on(); // calls led_switch::turn_on() since the real type of s2 is led_switch
But event if each object's behavior is dynamic on the the base of the real class of the object, the objects of the same class share a behavior that was predefined at compile time. If this is not ok, go to the next option.
Option 2: the member function pointer
The functions of another objects can only be invoked with that object at hand. So having a function pointer to a led function is not sufficient: you also need to know on which led it shall be applied.
This is why member function pointers are different and somewhat constraint: you can only invoke functions of class of your member function pointer. If polymorphism is sufficient (i.e. if derived class has a different implementation of a function already foreseen in the base classe) then you are lucky. If you want to use a function that only exists in the derived class and not in the base class, it won't compile.
Here a simplified version of auto_swith: I provide a function, but allso a pointer to the object on which the function has to be invoked:
class auto_switch{
void (led::*action)();
led *ld;
public:
auto_switch(void(led::*a)(), led*l) : action(a), ld(l) {}
void go () { (ld->*action)(); }
};
// usage:
auto_switch s(&led::turn_off, &l1);
s.go();
Online demo
Option 3 : the functional way (may that's what you're looking for ?)
Another variant would be to use the standard functional library to bind a member function and the object on which it shall be executed (as well as any need parameters):
class auto_switch{
std::function<void()> action;
public:
auto_switch(function<void()>a) : action(a) {}
void go () { action(); }
};
Here you can bind anything: any function of any class:
auto_switch s(bind(&led::turn_off, l1));
s.go();
auto_switch s2(bind(&blinking_led::blink, l2));
s2.go();
Online demo
Option 4 : command pattern
Now if you want to perform something on an object when you turn on and off the switch, but you need total flexibility, you can just implement the command pattern : this lets you execute anything on any object. And you don't even need a function pointer.
My goal is to access a class that is passed in as a parameter inside of myFunction.
Here's what I'm trying to do:
void myFunction(string myString)
{
callFunctionOn(OuterType::InnerType::myString);
}
I'm trying to call some function on something that's in a type. For example, my code in some other file might look like:
namespace OuterType {
namespace InnerType {
//stuff here
}
}
However, using myString in that way doesn't work. If myString holds the value "class1", then I want that callFunctionOn part to be interpreted as
callFunctionOn(OuterType::InnerType::class1);
I feel like this is super simple, but I've been programming all day and my mind grows tired...
SOLVED: It looks like in order to this in this way, I'd need a language with reflection. To solve this I took a different approach to the problem and passed in a pointer to the class instead.
C++ doesn't have reflection built in, but it does have pointers to data, functions, and class members. So you can use a std::map or unordered_set to find the pointer with a particular name (you have to add all the name/pointer pairs into the map beforehand).
Your solution is likely to look something like:
namespace Outer
{
namespace Inner
{
void funcA( void ) { std::cout << "called funcA" << std::endl; }
std::map< std::string, void (*)(void) > members;
}
}
// in some initialization function
Outer::Inner::members["funcA"] = &Outer::Inner::funcA;
// later
std::string myString = "funcA";
void (*f)(void) = Outer::Inner::members[myString]; // lookup function by name
(*f)(); // call function via its pointer
Of course the type of the pointer will probably need to change to meet your application requirements.
You're trying to access a variable based on a run-time string that contains its name? That's not possible; the names of variables disappear after compilation and linking. (Except insofar as they are kept around to facilitate debugging).
Do you mean :
OuterType::InnerType::callFunctionOn(myString);
maybe this idea: operator() can take parameters, wrapping it in a class ine can make calls that are resolved in the overloaded operator() based on its parameters.
template<typename TypeSig, class InstanceOf, typename NA,typename Args>
class FuncMap {
public:
typedef TypeSig (InstanceOf:: *cbMethod) ( NA, Args );
FuncMap( InstanceOf & cInst, cbMethod cbM ) : mcInst(cInst) {mcbM = cbM;}
TypeSig operator() ( NA na, Args args) {return (mcInst.*mcbM)(na, args);}
private:
InstanceOf & mcInst;
cbMethod mcbM;
};
you need to build a map of runtime string values as keys and pointers to instance methods as seen above. i used this for re-dispatch tracing and custom runtime dispatch with lesser than RTTI overhead.
this allows you to have default, if no key found, or other logic as you wish.
I am trying to store a vector(or stack) of functions. The idea is that I have a series of functions that add & remove widgets to the main window. I use a timer alarm & whenever the alarm is called I call the function at the top of the stack of functions.
So my functions will always be of type void. My problem/misunderstanding is how to delcare a stl::stack of void functions & how do I execute that function?
class InstructionScreen
{
std::stack <void*> instructionSteps; // is this how I declare a stack of functions
void runTimerEvent()
{
if ( !instructionSteps.empty() )
{
// call the function at the top of the stack
// how do I call the function?
(*instructionSteps.top()); // is that how?
instructionSteps.pop();
}
}
void step1()
{
// here I create some widgets & add them to the main window
}
void step2()
{
// delete widgets from window
// create some different widgets & add them to the main window
}
void buildStack()
{
instructionSteps.push( (&step1()) ); // is this correct?
instructionSteps.push( (&step2()) );
}
};
A void* pointer is not a legal function pointer. It should be void (*)(), which can be made nicer with a typedef void (*stack_function)().
std::stack<stack_function> instructionSteps;
To push something into it, you don't call the function (like you do with step1()) and you certainly don't take the address of the return (which is void anyways) like you do with &step1(), you just use the function name alone:
instructionSteps.push(step1); // the & can be omitted for free functions
instructionSteps.push(&step2); // equivalent to the above, only a different function
To call stuff from the top of the stack, you actually need to do a call:
(*instructionSteps.top())();
// you missed that -- ^^
The dereference can be omitted too for reasons that would take too long to explain here, search SO. :)
instructionSteps.top()();
The syntax for a static function pointer is like so:
void (*FuncPtr)();
For a member pointer you have to use this syntax:
void (class::*FuncPtr)();
If your functions does not require the functions to be member functions it is a lot cleaner. Once you figured out what kind of functions you need it's easiest to typedef these functions like so:
typedef void(*FuncPtrType)();
typedef void(Class::*MemberFuncPtrType)();
Now you can simply declare a stack with function pointers like so:
std::stack <FuncPtrType> funcPtrStack;
std::stack <MemberFuncPtrType> memberFuncPtrStack;
To get a pointer to a function you simply use the "&" operator like you would to get an address to any other data type in C++:
FuncPtrType funcPtr = &staticFunc; // Somewhere "void staticFunc()" is defined
MemberFuncPtrType memberFuncPtr = &Class::MemberFunc; // Somewhere void "Class::MemberFunc()" is defined
To actually call the function pointers, you would use the "*" operator to get the data back from the pointer (just like any other data type in C++). The only tricky thing is for member functions they need a pointer to the class which makes it very awkward to use. That's why I recommended using static functions to begin with. In any case, here is the syntax:
(*funcPtr)(); // I just called a function with a pointer!
(this->*memberFuncPtr)(); // I just wrote some ugly code to call a member function
Having shown all that, the following code should now make sense:
std::stack <MemberFuncPtrType> memberFuncPtrStack; // Declaring the stack
memberFuncPtrStack.push( &Class::MemberFunc ); // Pushing a function
(ClassPtr->*memberFuncPtrStack.top())(); // Calling the function with ClassPtr
Declare a typedef and make a vector/stack of it:
typedef void (*funcptr)();
std::stack<funcptr> instructionSteps;
Usage:
instructionSteps.push(&step1);
instructionSteps.push(&step2);
See demo here.
Execution:
instructionSteps.top()();
Tip: Use Boost.Function, it's a lot easier. It will not only store functions with precisely the right type, but also anything else that can be called in the same way.
std::stack<boost::function<void()> instructionSteps;
int foo() { return 42; }
instructionSteps.push(foo); // Close enough - return value will be discarded.
typedef void (*fptr)();
class InstructionScreen
{
std::stack <fptr> instructionSteps;
I would typedef the function pointer to make your life easier:
typedef void(*voidFunctionPointer)(); // Assuming here that the functions take no arguments.
std::stack<voidFunctionPointer> instructionSteps; // This is very different from <void*>.
// The latter is merely a stack of void pointers.
One way of calling the top function is this:
voidFunctionPointer functionToCall = instructionSteps.top();
functionToCall();
If you want to do it without an extra declaration, I think this should work. Please correct me if I'm wrong.
instructionSteps.top()();
To build the stack, just use the function name without any trailing parentheses.
instructionSteps.push(step1);
instructionSteps.push(step2);
// ...
I've read through this article, and what I take from it is that when you want to call a pointer to a member function, you need an instance (either a pointer to one or a stack-reference) and call it so:
(instance.*mem_func_ptr)(..)
or
(instance->*mem_func_ptr)(..)
My question is based on this: since you have the instance, why not call the member function directly, like so:
instance.mem_func(..) //or: instance->mem_func(..)
What is the rational/practical use of pointers to member functions?
[edit]
I'm playing with X-development & reached the stage where I am implementing widgets; the event-loop-thread for translating the X-events to my classes & widgets needs to start threads for each widget/window when an event for them arrives; to do this properly I thought I needed function-pointers to the event-handlers in my classes.
Not so: what I did discover was that I could do the same thing in a much clearer & neater way by simply using a virtual base class. No need whatsoever for pointers to member-functions. It was while developing the above that the doubt about the practical usability/meaning of pointers to member-functions arose.
The simple fact that you need a reference to an instance in order to use the member-function-pointer, obsoletes the need for one.
[edit - #sbi & others]
Here is a sample program to illustrate my point:
(Note specifically 'Handle_THREE()')
#include <iostream>
#include <string>
#include <map>
//-----------------------------------------------------------------------------
class Base
{
public:
~Base() {}
virtual void Handler(std::string sItem) = 0;
};
//-----------------------------------------------------------------------------
typedef void (Base::*memfunc)(std::string);
//-----------------------------------------------------------------------------
class Paper : public Base
{
public:
Paper() {}
~Paper() {}
virtual void Handler(std::string sItem) { std::cout << "Handling paper\n"; }
};
//-----------------------------------------------------------------------------
class Wood : public Base
{
public:
Wood() {}
~Wood() {}
virtual void Handler(std::string sItem) { std::cout << "Handling wood\n"; }
};
//-----------------------------------------------------------------------------
class Glass : public Base
{
public:
Glass() {}
~Glass() {}
virtual void Handler(std::string sItem) { std::cout << "Handling glass\n"; }
};
//-----------------------------------------------------------------------------
std::map< std::string, memfunc > handlers;
void AddHandler(std::string sItem, memfunc f) { handlers[sItem] = f; }
//-----------------------------------------------------------------------------
std::map< Base*, memfunc > available_ONE;
void AddAvailable_ONE(Base *p, memfunc f) { available_ONE[p] = f; }
//-----------------------------------------------------------------------------
std::map< std::string, Base* > available_TWO;
void AddAvailable_TWO(std::string sItem, Base *p) { available_TWO[sItem] = p; }
//-----------------------------------------------------------------------------
void Handle_ONE(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
std::map< Base*, memfunc >::iterator it;
Base *inst = NULL;
for (it=available_ONE.begin(); ((it != available_ONE.end()) && (inst==NULL)); it++)
{
if (it->second == f) inst = it->first;
}
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_TWO(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
Base *inst = available_TWO[sItem];
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_THREE(std::string sItem)
{
Base *inst = available_TWO[sItem];
if (inst) inst->Handler(sItem);
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
int main()
{
Paper p;
Wood w;
Glass g;
AddHandler("Paper", (memfunc)(&Paper::Handler));
AddHandler("Wood", (memfunc)(&Wood::Handler));
AddHandler("Glass", (memfunc)(&Glass::Handler));
AddAvailable_ONE(&p, (memfunc)(&Paper::Handler));
AddAvailable_ONE(&g, (memfunc)(&Glass::Handler));
AddAvailable_TWO("Paper", &p);
AddAvailable_TWO("Glass", &g);
std::cout << "\nONE: (bug due to member-function address being relative to instance address)\n";
Handle_ONE("Paper");
Handle_ONE("Wood");
Handle_ONE("Glass");
Handle_ONE("Iron");
std::cout << "\nTWO:\n";
Handle_TWO("Paper");
Handle_TWO("Wood");
Handle_TWO("Glass");
Handle_TWO("Iron");
std::cout << "\nTHREE:\n";
Handle_THREE("Paper");
Handle_THREE("Wood");
Handle_THREE("Glass");
Handle_THREE("Iron");
}
{edit] Potential problem with direct-call in above example:
In Handler_THREE() the name of the method must be hard-coded, forcing changes to be made anywhere that it is used, to apply any change to the method. Using a pointer to member-function the only additional change to be made is where the pointer is created.
[edit] Practical uses gleaned from the answers:
From answer by Chubsdad:
What: A dedicated 'Caller'-function is used to invoke the mem-func-ptr;Benefit: To protect code using function(s) provided by other objectsHow: If the particular function(s) are used in many places and the name and/or parameters change, then you only need to change the name where it is allocated as pointer, and adapt the call in the 'Caller'-function. (If the function is used as instance.function() then it must be changed everywhere.)
From answer by Matthew Flaschen:
What: Local specialization in a classBenefit: Makes the code much clearer,simpler and easier to use and maintainHow: Replaces code that would conventionally be implement using complex logic with (potentially) large switch()/if-then statements with direct pointers to the specialization; fairly similar to the 'Caller'-function above.
The same reason you use any function pointer: You can use arbitrary program logic to set the function pointer variable before calling it. You could use a switch, an if/else, pass it into a function, whatever.
EDIT:
The example in the question does show that you can sometimes use virtual functions as an alternative to pointers to member functions. This shouldn't be surprising, because there are usually multiple approaches in programming.
Here's an example of a case where virtual functions probably don't make sense. Like the code in the OP, this is meant to illustrate, not to be particularly realistic. It shows a class with public test functions. These use internal, private, functions. The internal functions can only be called after a setup, and a teardown must be called afterwards.
#include <iostream>
class MemberDemo;
typedef void (MemberDemo::*MemberDemoPtr)();
class MemberDemo
{
public:
void test1();
void test2();
private:
void test1_internal();
void test2_internal();
void do_with_setup_teardown(MemberDemoPtr p);
};
void MemberDemo::test1()
{
do_with_setup_teardown(&MemberDemo::test1_internal);
}
void MemberDemo::test2()
{
do_with_setup_teardown(&MemberDemo::test2_internal);
}
void MemberDemo::test1_internal()
{
std::cout << "Test1" << std::endl;
}
void MemberDemo::test2_internal()
{
std::cout << "Test2" << std::endl;
}
void MemberDemo::do_with_setup_teardown(MemberDemoPtr mem_ptr)
{
std::cout << "Setup" << std::endl;
(this->*mem_ptr)();
std::cout << "Teardown" << std::endl;
}
int main()
{
MemberDemo m;
m.test1();
m.test2();
}
My question is based on this: since you have the instance, why not call the member function directly[?]
Upfront: In more than 15 years of C++ programming, I have used members pointers maybe twice or thrice. With virtual functions being around, there's not all that much use for it.
You would use them if you want to call a certain member functions on an object (or many objects) and you have to decide which member function to call before you can find out for which object(s) to call it on. Here is an example of someone wanting to do this.
I find the real usefulness of pointers to member functions comes when you look at a higher level construct such as boost::bind(). This will let you wrap a function call as an object that can be bound to a specific object instance later on and then passed around as a copyable object. This is a really powerful idiom that allows for deferred callbacks, delegates and sophisticated predicate operations. See my previous post for some examples:
https://stackoverflow.com/questions/1596139/hidden-features-and-dark-corners-of-stl/1596626#1596626
Member functions, like many function pointers, act as callbacks. You could manage without them by creating some abstract class that calls your method, but this can be a lot of extra work.
One common use is algorithms. In std::for_each, we may want to call a member function of the class of each member of our collection. We also may want to call the member function of our own class on each member of the collection - the latter requires boost::bind to achieve, the former can be done with the STL mem_fun family of classes (if we don't have a collection of shared_ptr, in which case we need to boost::bind in this case too). We could also use a member function as a predicate in certain lookup or sort algorithms. (This removes our need to write a custom class that overloads operator() to call a member of our class, we just pass it in directly to boost::bind).
The other use, as I mentioned, are callbacks, often in event-driven code. When an operation has completed we want a method of our class called to handle the completion. This can often be wrapped into a boost::bind functor. In this case we have to be very careful to manage the lifetime of these objects correctly and their thread-safety (especially as it can be very hard to debug if something goes wrong). Still, it once again can save us from writing large amounts of "wrapper" code.
There are many practical uses. One that comes to my mind is as follows:
Assume a core function such as below (suitably defined myfoo and MFN)
void dosomething(myfoo &m, MFN f){ // m could also be passed by reference to
// const
m.*f();
}
Such a function in the presence of pointer to member functions, becomes open for extension and closed for modification (OCP)
Also refer to Safe bool idiom which smartly uses pointer to members.
The best use of pointers to member functions is to break dependencies.
Good example where pointer to member function is needed is Subscriber/Publisher pattern :
http://en.wikipedia.org/wiki/Publish/subscribe
In my opinion, member function pointers do are not terribly useful to the average programmer in their raw form. OTOH, constructs like ::std::tr1::function that wrap member function pointers together with a pointer to the object they're supposed to operate on are extremely useful.
Of course ::std::tr1::function is very complex. So I will give you a simple example that you wouldn't actually use in practice if you had ::std::tr1::function available:
// Button.hpp
#include <memory>
class Button {
public:
Button(/* stuff */) : hdlr_(0), myhandler_(false) { }
~Button() {
// stuff
if (myhandler_) {
delete hdlr_;
}
}
class PressedHandler {
public:
virtual ~PressedHandler() = 0;
virtual void buttonPushed(Button *button) = 0;
};
// ... lots of stuff
// This stores a pointer to the handler, but will not manage the
// storage. You are responsible for making sure the handler stays
// around as long as the Button object.
void setHandler(const PressedHandler &hdlr) {
hdlr_ = &hdlr;
myhandler_ = false;
}
// This stores a pointer to an object that Button does not manage. You
// are responsible for making sure this object stays around until Button
// goes away.
template <class T>
inline void setHandlerFunc(T &dest, void (T::*pushed)(Button *));
private:
const PressedHandler *hdlr_;
bool myhandler_;
template <class T>
class PressedHandlerT : public Button::PressedHandler {
public:
typedef void (T::*hdlrfuncptr_t)(Button *);
PressedHandlerT(T *ob, hdlrfuncptr_t hdlr) : ob_(ob), func_(hdlr) { }
virtual ~PressedHandlerT() {}
virtual void buttonPushed(Button *button) { (ob_->*func_)(button); }
private:
T * const ob_;
const hdlrfuncptr_t func_;
};
};
template <class T>
inline void Button::setHandlerFunc(T &dest, void (T::*pushed)(Button *))
{
PressedHandler *newhandler = new PressedHandlerT<T>(&dest, pushed);
if (myhandler_) {
delete hdlr_;
}
hdlr_ = newhandler;
myhandler_ = true;
}
// UseButton.cpp
#include "Button.hpp"
#include <memory>
class NoiseMaker {
public:
NoiseMaker();
void squee(Button *b);
void hiss(Button *b);
void boo(Button *b);
private:
typedef ::std::auto_ptr<Button> buttonptr_t;
const buttonptr_t squeebutton_, hissbutton_, boobutton_;
};
NoiseMaker::NoiseMaker()
: squeebutton_(new Button), hissbutton_(new Button), boobutton_(new Button)
{
squeebutton_->setHandlerFunc(*this, &NoiseMaker::squee);
hissbutton_->setHandlerFunc(*this, &NoiseMaker::hiss);
boobutton_->setHandlerFunc(*this, &NoiseMaker::boo);
}
Assuming Button is in a library and not alterable by you, I would enjoy seeing you implement that cleanly using a virtual base class without resorting to a switch or if else if construct somewhere.
The whole point of pointers of pointer-to-member function type is that they act as a run-time way to reference a specific method. When you use the "usual" syntax for method access
object.method();
pointer->method();
the method part is a fixed, compile-time specification of the method you want to call. It is hardcoded into your program. It can never change. But by using a pointer of pointer-to-member function type you can replace that fixed part with a variable, changeable at run-time specification of the method.
To better illustrate this, let me make the following simple analogy. Let's say you have an array
int a[100];
You can access its elements with fixed compile-time index
a[5]; a[8]; a[23];
In this case the specific indices are hardcoded into your program. But you can also access array's elements with a run-time index - an integer variable i
a[i];
the value of i is not fixed, it can change at run-time, thus allowing you to select different elements of the array at run-time. That is very similar to what pointers of pointer-to-member function type let you do.
The question you are asking ("since you have the instance, why not call the member function directly") can be translated into this array context. You are basically asking: "Why do we need a variable index access a[i], when we have direct compile-time constant access like a[1] and a[3]?" I hope you know the answer to this question and realize the value of run-time selection of specific array element.
The same applies to pointers of pointer-to-member function type: they, again, let you to perform run-time selection of a specific class method.
The use case is that you have several member methods with the same signature, and you want to build logic which one should be called under given circumstances. This can be helpful to implement state machine algorithms.
Not something you use everyday...
Imagine for a second you have a function that could call one of several different functions depending on parameters passed.
You could use a giant if/else if statement
You could use a switch statement
Or you could use a table of function pointers (a jump table)
If you have a lot of different options the jump table can be a much cleaner way of arranging your code ...
Its down to personal preference though. Switch statement and jump table correspond to more or less the same compiled code anyway :)
Member pointers + templates = pure win.
e.g. How to tell if class contains a certain member function in compile time
or
template<typename TContainer,
typename TProperty,
typename TElement = decltype(*Container().begin())>
TProperty grand_total(TContainer& items, TProperty (TElement::*property)() const)
{
TProperty accum = 0;
for( auto it = items.begin(), end = items.end(); it != end; ++it) {
accum += (it->*property)();
}
return accum;
}
auto ship_count = grand_total(invoice->lineItems, &LineItem::get_quantity);
auto sub_total = grand_total(invoice->lineItems, &LineItem::get_extended_total);
auto sales_tax = grand_total(invoice->lineItems, &LineItem::calculate_tax);
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
This is completely missing the point. There are two indepedent concerns here:
what action to take at some later point in time
what object to perform that action on
Having a reference to an instance satisfies the second requirement. Pointers to member functions address the first: they are a very direct way to record - at one point in a program's execution - which action should be taken at some later stage of execution, possibly by another part of the program.
EXAMPLE
Say you have a monkey that can kiss people or tickle them. At 6pm, your program should set the monkey loose, and knows whom the monkey should visit, but around 3pm your user will type in which action should be taken.
A beginner's approach
So, at 3pm you could set a variable "enum Action { Kiss, Tickle } action;", then at 6pm you could do something like "if (action == Kiss) monkey->kiss(person); else monkey->tickle(person)".
Issues
But that introducing an extra level of encoding (the Action type's introduced to support this - built in types could be used but would be more error prone and less inherently meaningful). Then - after having worked out what action should be taken at 3pm, at 6pm you have to redundantly consult that encoded value to decide which action to take, which will require another if/else or switch upon the encoded value. It's all clumsy, verbose, slow and error prone.
Member function pointers
A better way is to use a more specialised varibale - a member function pointer - that directly records which action to perform at 6pm. That's what a member function pointer is. It's a kiss-or-tickle selector that's set earlier, creating a "state" for the monkey - is it a tickler or a kisser - which can be used later. The later code just invokes whatever function's been set without having to think about the possibilities or have any if/else-if or switch statements.
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
Back to this. So, this is good if you make the decision about which action to take at compile time (i.e. a point X in your program, it'll definitely be a tickle). Function pointers are for when you're not sure, and want to decouple the setting of actions from the invocation of those actions.