Pointer to function from another pointer - c++

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.

Related

Passing function pointer with scope resolution operator arduino

I'm a newbie to arduino and programming.
I've included a library inside my own library in arduino, but first library contains a function which has a pointer function as a parameter. It is an interrupt service routine(ISR) but I need to call a function in my cpp file when interrupt is occurred. So I need to pass the pointer of that function to the first library code. It works well when I use it in .ino file, I can pass it like,
attachInterrupt(functionISR_name);
but when I use it in .cpp file, I get errors. my function is like,
void velocity::functionISR_name(){
//some code
}
but how can I pass the pointer of this function to the first library function? I tried this way but got errors,
attachInterrupt(velocity::functionISR_name);
You cannot pass a method to a function which expects a function, unless you define it static.
write it static :
static void velocity::functionISR_name()
and
attachInterrupt(&velocity::functionISR_name);
Unfortunately the static method is not bound to a specific instance any more. You should use it only together with a singleton. On Arduino you should write the class like shown below in the code snipped:
class velocity
{
static velocity *pThisSingelton;
public:
velocity()
{
pThisSingelton=this;
}
static void functionISR_name()
{
pThisSingelton->CallWhatEverMethodYouNeeded();
// Do whatever needed.
}
// … Your methods
};
velocity *velocity::pThisSingelton;
velocity YourOneAndOnlyInstanceOfThisClass;
void setup()
{
attachInterrupt(&velocity::functionISR_name);
// …other stuff…
}
This looks ugly, but in my opinion it is totally okay with Arduino as the opportunities are very limited on such a system.
Thinking again over it, I would personal go for the approach Sorin mentioned in his answer above. That would be more like that:
class velocity
{
public:
velocity()
{
}
static void functionISR_name()
{
// Do whatever needed.
}
// … Your methods
};
velocity YourOneAndOnlyInstanceOfThisClass;
void functionISR_name_delegation()
{
YourOneAndOnlyInstanceOfThisClass.functionISR_name();
}
void setup()
{
attachInterrupt(functionISR_name_delegation);
// …other stuff…
}
It would also save you some bytes for the pointer you need in the first example.
As a site note: For the future, please post the exact code (for e.g. attachInterrupt needs more parameter) and copy&paste the error messages. Usually error are exact at a place you do not suspect. This question was an exception. Normally I and other would ask for better specification.
You pass a pointer to the function but the function is a class member. Likely the call will be invalid because the this pointer will be garbage(may compile fine but will throw strange errors at runtime).
You need to define a plain vanilla function, outside of any class, and use that.
If you don't have a very complex project you can get away with having a global pointer to the class instance you should use and just delegate the call in your new function.
If you want to do thing the right way you need some mechanism to get the instance pointer I talked about above. Usually this involves either a singleton or some factory pattern.
Example:
class Foo {
void method() {
x = 5;
}
int x;
}
Having a callback on method will crash because you have an invalid pointer for this so x=5 will write 5 somewhere randomly in memory.
What you need is somehting like:
static Foo* foo_instance; // Initialized somewhere else.
void method_delegator() {
foo_instance->method();
}
Now you can pass method_delegator to the function. It will work because you now also pass foo_instance for this pointer.

Callback function pointers C++ with/without classes

I got stuck. I am trying to form a function that will eat classless function pointers and ones from objects. Here is my current code that hopefully explains more.
(It should run on a Arduino, so I cannot use big libraries.)
First off, I am using this library for the Arduino:
/* SimpleTimer - A timer library for Arduino.
* Author: mromani#ottotecnica.com
* Copyright (c) 2010 OTTOTECNICA Italy
*/
Which takes functions which it calls on a set timer interval of this type:
typedef void (*timer_callback)(void);
As far as my knowledge goes, it's a classles function, the webpage Pointers to member functions got me really far but, not far enough. Probably a terminology deficit on my side.
Now, I have made my own class which I would like in turn to use this SimpleTimer library. But if I feed the SimpleTimer my class functions, it does not like them (what I understand). But how would it be possible to make this happen without altering the SimpleTimer library.
So there is the class Robot, which has Robot::halt(). I want the robot to move forward for a set amount of time. Like so:
void Robot::forward(int speed, long time) {
reset();
timer.setTimer(time, c_func, 1);
analogWrite(l_a, speed);
analogWrite(r_a, speed);
isMoving(true);
}
void Robot::halt() {
__isMoving = false;
digitalWrite(r_a, LOW);
digitalWrite(r_b, LOW);
digitalWrite(l_b, LOW);
digitalWrite(l_a, LOW);
}
The c_func variable is a classless function at this point, but I would like to use the Robot::halt function. I have looked, read, learned but haven't succeeded yet. I just can't seem to wrap my head around this one because I am missing some angle.
I tried:
timer.setTimer(time, (this->*halt), 1);
timer.setTimer(time, Robot::*halt, 1);
timer.setTimer(time, &Robot::halt), 1);
But it would all amount to the same problem/ me just stabbing in the dark here...
EDIT
Earlier, I said not wanting to change the SimpleTimer library code. I want to comeback on this one, I guess altering it there would be the better option.
Thanks for all the current answers already, I was only allowed to flag one as a viable answer, actually everyhting I read here was extremely helpful.
To continue this, changing the SimpleTimer code. This class needs to have a reference to the object that holds my "halt" function, right? So, overloading the settimer function to something that takes my object and my function as two seperate pointers would work...? I think I am getting the hang of this but, I am not there yet with my head.
EDIT
I don't know who came with this one again but, anyone finding this thread. If found Member Function Pointers and the Fastest Possible C++ Delegates to give a very nice introduction in function pointers and member function pointers.
EDIT
Got it working, changed the SimpleTimer library to use this Delegate system:
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
It integrated very nicely, and it could be nice to have a standard Delegate system like this in the Arduino library.
Code as in test (working)
typedef
typedef FastDelegate0<> FuncDelegate;
Code in robot class:
void Robot::test(){
FuncDelegate f_delegate;
f_delegate = MakeDelegate(this, &Robot::halt);
timer.setTimerDelg(1, f_delegate, 1);
}
void Robot::halt() {
Serial.println("TEST");
}
Code in SimpleTimer class:
int SimpleTimer::setTimerDelg(long d, FuncDelegate f, int n){
f();
}
Arduino prints TEST in the console.
Next step putting it in an array, don't see a lot of problems there. Thanks everyone, I can't believe the stuff I learned in two days.
What's that smell? Is that the smell of...? Success!
For the ones interested, the used Delegate system does not amount to memory capacity issues:
With FastDelegate
AVR Memory Usage
----------------
Device: atmega2560
Program: 17178 bytes (6.6% Full)
(.text + .data + .bootloader)
Data: 1292 bytes (15.8% Full)
(.data + .bss + .noinit)
Finished building: sizedummy
Without FastDelegate:
AVR Memory Usage
----------------
Device: atmega2560
Program: 17030 bytes (6.5% Full)
(.text + .data + .bootloader)
Data: 1292 bytes (15.8% Full)
(.data + .bss + .noinit)
Finished building: sizedummy
You can do this by making a functor object, that acts as a proxy between the timer code and your code.
class MyHaltStruct
{
public:
MyHaltStruct(Robot &robot)
: m_robot(robot)
{ }
void operator()()
{ robot.halt(); }
private:
Robot &m_robot;
}
// ...
timer.setTimer(time, MyHaltStruct(*this), 1);
Edit
If it can't be done via a functor object, you could global variables and functions instead, maybe in a namespace:
namespace my_robot_halter
{
Robot *robot = 0;
void halt()
{
if (robot)
robot->halt();
}
}
// ...
my_robot_halter::robot = this;
timer.setTimer(time, my_robot_halter::halt, 1);
This only works if you have one robot instance though.
Since the timer callback signature doesn't take any argument, you unfortunately need to use some global (or static) state:
Robot *global_robot_for_timer;
void robot_halt_callback()
{
global_robot_for_timer->halt();
}
you can at least wrap that lot into it's own file, but it isn't pretty. As Matthew Murdoch suggested, it might be better to edit the SimpleTimer itself. A more conventional interface would be:
typedef void (*timer_callback)(void *);
SimpleTimer::setTimer(long time, timer_callback f, void *data);
void robot_halt_callback(void *data)
{
Robot *r = (Robot *)data;
r->halt();
}
ie, when you call setTimer, you provide an argument which is passed back to the callback.
The smallest change to SimpleTimer would be something like:
SimpleTimer.h
typedef void (*timer_function)(void *);
struct timer_callback {
timer_function func;
void *arg;
};
// ... every method taking a callback should look like this:
int SimpleTimer::setTimeout(long, timer_function, void *);
SimpleTimer.cpp
// ... callbacks is now an array of structures
callbacks[i] = {0};
// ... findFirstFreeSlot
if (callbacks[i].func == 0) {
// ... SimpleTimer::setTimer can take the timer_callback structure, but
// that means it's callers have to construct it ...
int SimpleTimer::setTimeout(long d, timer_function func, void *arg) {
timer_callback cb = {func, arg};
return setTimer(d, cb, RUN_ONCE);
}
You can't pass a non-static member function there - only a static one. The signature should be like this:
static void halt()
{
//implementation
}
the reason is that each non-static member function has an implicit Robot* parameter known as this pointer which facilitates access to the current object. Since the callback signature doesn't have such Robot* parameter you can't possibly pass a member function of class Robot unless it is static.
So that in your implementation
void halt();
is in effect
static void halt( Robot* thisPointer );
and when you do
void Robot::halt() {
__isMoving = false;
}
you effectively have this:
void Robot::halt( Robot* thisPointer ) {
thisPointer->__isMoving = false;
}
and of course a halt( Robot*) function pointer can't be passed in place of void (*)(void) C callback function.
And yes, if you need access to non-static member variables of class Robot from inside the callback you'll have to somehow retrieve the pointer to class Robot instance elsewhere - for example, store it as a static member variable so that you don't rely on this pointer.
It's important to understand that function pointers and pointers to class members are different not for an arbitrary reason but the fact that instance methods have an implicit this argument (also, they have to work with inherited and virtual functions, which adds even more complexity; hence they can be 16 or more bytes in size). In other words, a function pointer to a class member is only meaningful together with an instance of the class.
As the currently-top answer says, your best bet is to go with functors. While the setTimer function might only accept function pointers, it is possible to write a template function to wrap the call and accept both. For even more fine-grained processing, you can write a template metaprogram (Boost.TypeTraits has is_pointer, is_function and even is_member_function_pointer) to handle the different cases.
How you make the functors is a different story. You can opt for writing them by hand (which means implementing a class with operator() for each one of them), but depending on your needs that might be tedious. A couple of options:
std::bind: you can use it to create a functor whose first parameter will be bound to the value you specify - in the case of member functions, it will be the instance.
Depending on your compiler, you might not have access to std::bind - in this case I suggest boost::bind. It is a header-only library and provides the same functionality.
You can use another delegate implementation. I don't have experience with this one, but claims to be faster than other implementations (including std::function).
The mentioned libraries are header-only, so they probably don't count as "big libraries".

Nested Classes C++ static inner methods (Xml parsing and trying to populate vector with values)

So this is what I am trying to accomplish. I am trying to use a sax parser to parse some XML. it looks like I need to call all their methods as statics. So if I want to pass a value back from say startElement it is static void startElement. Which brings me to my example code. I have been pulling my hair on how to update a value in a Nesting class from a static member function.
I have looked at several things such as defining OuterClass * oc; then trying to reference oc->allRecords, but since it is a static method inside, it fails. I am sure I am doing something wrong architecturally, so any feedback on what would be the right way to do this would be a great help. Thanks.
class Attribute {
string AttributeName;
string AttributeValue;
};
typedef shared_ptr<Attribute> AttributePtr;
class AttributeSet {
vector<AttributePtr> Attributes;
};
typedef shared_ptr<AttributeSet> AttributeSetPtr;
class OuterClass {
public :
vector<AttributeSetPtr> allRecords;
class InnerClass {
public:
static mymethod1() {
// I need to be able to set attributes here :
// This would be the characters method for sax parsing
// What is the right way to Attributes.push_back(new Attribute(Name,Value));
}
static mymethod2() {
// I also need to be able to add Records here :
// This would be the endElement for sax parsing
// What is the right way to allRecords.push_back(AttributeSet);
}
};
// EDIT: CALLING CODE GOES HERE (WAS EDITED - SEE BELOW)
};
// ADDING INFORMATION REGARDING HOW METHOD 1 & 2 are called
xmlSAXHandler saxHandler;
memset(&saxHandler, 0, sizeof(saxHandler));
saxHandler.initialized = XML_SAX2_MAGIC;
...
saxHandler.endElementsNs = &InnerClass::method2;
saxHandler.characters = &InnerClass::method1;
...
InnerClass innerXmlParsingClass
xmlSaxUserParseMemory( &saxHandler, &innerXmlParsingClass, xmlString, xmlString.length());
Your mistake is using an inner class (are you coming from Java?).
I don't know what you believe you are are achieving with an inner class, but it won't work. Don't use inner classes in C++ unless you really know what it does (for inner classes, protected and private members of the outer classes are seen as if they were public).
Now, as the solution to your problem, I guess it depends on the implementation you're using (I used once Apache's Xerces SAX, but I know Microsoft offers its own SAX implementation, and that there should be a lot other alternatives, so...)
Edit
After the comment, I found the following tutorial:
http://www.jamesh.id.au/articles/libxml-sax/libxml-sax.html
I must say that, coming from Java to C++, and using a C API, you have a kind of courage...
:-D
If you are not familiar enough with function pointers, and C in general, using libxml2 will be a challenge. Be sure that in the end, you will understand those notions... Note that C have a way to handle the data that C++, Java or C# developers associate to this. The C way is to pass a pointer to your data (the user data) to a function, and when the callback is called, it passes back this pointer, typed as a void *. You must then cast it back to its right type, and voilà, you have your this back.
:-)
Anyway, reading the doc, I see that when you parse the file, you'll call the following C function:
int xmlSAXUserParseFile( xmlSAXHandlerPtr sax,
void * user_data,
const char * filename);
the user_data part is the one that interest you because it enables you to have a context. So, wrapping this function in a C++ class, you could have something like:
// MySaxBase.hpp
class MySaxBase
{
public :
MySaxBase() ;
int parseFile(const std::string & p_filename) ;
virtual void startDocument() ;
virtual void endDocument() ;
private :
static void do_startDocument(void *p_user_data) ;
static void do_endDocument(void *p_user_data) ;
xmlSAXHandler m_sax ;
}
.
// MySaxBase.cpp
extern "C"
{
void do_startDocument(void *p_user_data)
{
// this static method will convert the p_user_data into
// the this pointer...
MySaxBase * saxBase = static_cast<MySaxBase *>(p_user_data) ;
// ...and call the right virtual method
saxBase->startDocument() ;
}
void do_endDocument(void *p_user_data)
{
// this static method will convert the p_user_data into
// the this pointer...
MySaxBase * saxBase = static_cast<MySaxBase *>(p_user_data) ;
// ...and call the right virtual method
saxBase->endDocument() ;
}
} // extern "C"
MySaxBase::MySaxBase()
{
// the m_sax structure must be set to zero to NULL all its
// pointers to functions
memset(&m_sax, 0, sizeof(xmlSAXHandler)) ;
// Now, we initialize some pointers to the static method we
// want to be called
this->m_sax.startDocument = do_startDocument ;
this->m_sax.endDocument = do_endDocument ;
}
int MySaxBase::parseFile(const std::string & p_filename)
{
// the important thing, here, is the this pointer, passed as
// a user_data parameter
return xmlSAXUserParseFile(&m_sax, this, p_filename.c_str()) ;
}
void MySaxBase::startDocument()
{
// The document started. Override this method to
// actually do something
}
void MySaxBase::endDocument()
{
// The document ended. Override this method to
// actually do something
}
I did not test this, and I never used libxml2, but I guess the code must be Ok, and this should be enough for you to continue on your own: Just add the methods you want to support, initialize the sax handler with the relevant function pointers, and you'll have your class complete.
The MySaxBase::startDocument and MySaxBase::endDocument methods are virtual just for you to derive from MySaxBase and then override those methods.
Edit 2
I'll reproduce here Steve Jessop's excellent comment:
+1. One tiny quibble - I don't think that static member functions are guaranteed by the C++ standard to have C linkage / calling convention, but to use them as a callback from a C API, that's what they need. I don't specifically know what implementations it makes a difference, but for safety do_startDocument should be a free function declared with extern "C". On the same subject: a Java programmer may not realise you have make sure that the function can't throw an exception (because C doesn't have them). So you'd normally want to see a try/catch(...) in the wrapper function. – Steve Jessop
Following this, and after reading Johannes Schaub - litb (who else?) no less excellent answer at static vs extern "C"/"C++" , I modified the code to make do_startDocument and do_endDocument real C functions (i.e. wrapped in an extern "C" block). This usually is not important (I never encountered this kind of problem), but, better safe than sorry.
Your basic problem is that static methods are not per-instance, so there is no this pointer. You somehow need to get a OuterClass* passed to mymethod1 and mymethod2.
If you show us how mymethod1 and mymethod2 are called, we can help you further.
If it's simply called by you someplace where you have a OuterClass object, then your solution is simple:
class OuterClass
{
// ...
static void mymethod1(OuterClass* oc)
{
oc->all_records.push_back( something );
}
};
void some_func()
{
OuterClass oc;
OuterClass::method1(&oc);
}
Since you updated your question here is how you should do this:
class OuterClass {
public:
vector<AttributeSetPtr> allRecords;
void characters(const xmlChar* ch, int len)
{
// do here whatever you want
allRecords.push_back(bla bla);
}
static void static_characters(void* ctx, const xmlChar* ch, int len) {
// retrieve this pointer from ctx
static_cast<OuterClass*>(ctx)->characters(ch, len);
}
};
saxHandler.characters = &OuterClass::static_characters;
...
OuterClass outerClass;
xmlSaxUserParseMemory(&saxHandler, static_cast<void*>(&outerClass), xmlString, xmlString.length());

What is the practical use of pointers to member functions?

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.

C++: static function wrapper that routes to member function?

I've tried all sorts of design approaches to solve this problem, but I just can't seem to get it right.
I need to expose some static functions to use as callback function to a C lib. However, I want the actual implementation to be non-static, so I can use virtual functions and reuse code in a base class. Such as:
class Callbacks {
static void MyCallBack() { impl->MyCallBackImpl(); }
...
class CallbackImplBase {
virtual void MyCallBackImpl() = 0;
However I try to solve this (Singleton, composition by letting Callbacks be contained in the implementor class, etc) I end up in a dead-end (impl usually ends up pointing to the base class, not the derived one).
I wonder if it is at all possible or if I'm stuck with creating some sort of helper functions instead of using inheritance?
Problem 1:
Though it may look and seem to work on your setup this is not guaranteed to work as the C++ ABI is not defined. So technically you can not use C++ static member functions as functions pointers to be used by C code.
Problem 2:
All C callacks (that I know of) allow you to pass user data back as a void*. You can use this as the pointer to your object that has the virtual method. BUT You must make sure you use dynamic_cast<>() to the base class (the one with the virtual method used in the callback) before it is converted into the void* otherwise the pointer at the other end may not be interpreted correctly (especially if there is multiple inheritance involved).
Problem 3:
Exceptions: C is not designed to work with exceptions (especially old C libraries with callbacks). So don't expect exceptions that escape your callback to provide anything meaningful to the caller (they are more likely to result in application termination).
Solution:
What you need to do is use extern "C" function as the callback that calls the virtual method on an object of know type and throws away all exceptions.
An example for the C pthread routines
#include <iostream>
extern "C" void* start_thread(void* data);
class Work
{
public:
virtual ~Work() {}
virtual void doWork() = 0;
};
/*
* To be used as a callback for C code this MUST be declared as
* with extern "C" linkage to make sure the calling code can
* correctly call it
*/
void* start_thread(void* data)
{
/*
* Use reinterpret_cast<>() because the only thing you know
* that you can do is cast back to a Work* pointer.
*
*/
Work* work = reinterpret_cast<Work*>(data);
try
{
work->doWork();
}
catch(...)
{
// Never let an exception escape a callback.
// As you are being called back from C code this would probably result
// in program termination as the C ABI does not know how to cope with
// exceptions and thus would not be able to unwind the call stack.
//
// An exception is if the C code had been built with a C++ compiler
// But if like pthread this is an existing C lib you are unlikely to get
// the results you expect.
}
return NULL;
}
class PrintWork: public Work
{
public:
virtual void doWork()
{
std::cout << "Hi \n";
}
};
int main()
{
pthread_t thread;
PrintWork printer;
/*
* Use dynamic_cast<>() here because you must make sure that
* the underlying routine receives a Work* pointer
*
* As it is working with a void* there is no way for the compiler
* to do this intrinsically so you must do it manually at this end
*/
int check = pthread_create(&thread,NULL,start_thread,dynamic_cast<Work*>(&printer));
if (check == 0)
{
void* result;
pthread_join(thread,&result);
}
}
It's possible. Perhaps there's a problem on how you're initializing the concrete implementation?
In fact, I remember one library that does something very similar to this. You might find it usefull to take a look at libxml++ source code. It's built on top of libxml, which is a C library.
libxml++ uses a struct of static functions to handle the callbacks. For customization, the design allows the user to provide (through virtual functions) his/her own implementations to which the callbacks are then forwarded. I guess this is pretty much your situation.
Something like the below. The singleton is in class Callback, the Instance member will return a statically allocated reference to a CallbackImpl class. This is a singleton because the reference will only be initialised once when the function is first called. Also, it must be a reference or a pointer otherwise the virtual function will not work.
class CallbackImplBase
{
public:
virtual void MyCallBackImpl() = 0;
};
class CallbackImpl : public CallbackImplBase
{
public:
void MyCallBackImpl()
{
std::cout << "MyCallBackImpl" << std::endl;
}
};
class Callback
{
public:
static CallbackImplBase & Instance()
{
static CallbackImpl instance;
return instance;
}
static void MyCallBack()
{
Instance().MyCallBackImpl();
}
};
extern "C" void MyCallBack()
{
Callback::MyCallBack();
}
Are any of the parameters passed to the callback function user defined? Is there any way you can attach a user defined value to data passed to these callbacks? I remember when I implemented a wrapper library for Win32 windows I used SetWindowLong() to attach a this pointer to the window handle which could be later retrieved in the callback function. Basically, you need to pack the this pointer somewhere so that you can retrieve it when the callback gets fired.
struct CALLBACKDATA
{
int field0;
int field1;
int field2;
};
struct MYCALLBACKDATA : public CALLBACKDATA
{
Callback* ptr;
};
registerCallback( Callback::StaticCallbackFunc, &myCallbackData, ... );
void Callback::StaticCallbackFunc( CALLBACKDATA* pData )
{
MYCALLBACKDATA* pMyData = (MYCALLBACKDATA*)pData;
Callback* pCallback = pMyData->ptr;
pCallback->virtualFunctionCall();
}