Reputation: 3125
I am new to pointer to member functions, and I would like to know their pros and cons.
Specifically, consider this:
#include <iostream>
#include <list>
using namespace std;
class VariableContainer;
class Variable
{
public:
Variable (int v) : value (v), cb_pointer (0) {}
~Variable () {}
void SetCallback (void (VariableContainer::*cb)(int)) {
cb_pointer = cb;
}
void FireCallback (void) {
/* I need a reference to a VariableContainer object! */
}
private:
int value;
void (VariableContainer::*cb_pointer) (int);
};
class VariableContainer
{
public:
VariableContainer () {}
~VariableContainer () {}
void AddVar (Variable &v) {
v.SetCallback (&VariableContainer::Callback);
}
void Callback (int v) { cout << v << endl; }
};
int main ()
{
Variable v (1);
VariableContainer vc;
vc.AddVar (v);
v.FireCallback();
return 0;
}
As stated in the comment, to trigger the callback (FireCallback
) I need some reference to an existing VariableContainer
object, which should be provided as an additional argument of VariableContainer::AddVar (...)
.
Now:
Callback (...)
(since I have a pointer to the VariableContainer
object)?TIA, Jir
Upvotes: 0
Views: 220
Reputation: 41509
Depending on what will vary in the future, you can decide:
arg->CallBack()
directly.A possible solution to the problem is using an interface layer: this is no more than an implementation of the Observer pattern. This is a little more OO, hence verbose, but the syntax is way easier.
class Observer {
public:
virtual ~Observer(){};
virtual void callback( int v ) = 0;
};
// actual implementation
class MyCallbackObserver : public Observer {
virtual void callback( int v ) { std::cout << v << std::endl; }
void some_other_method( int v ) { std::cout << "other " << v ; }
};
And your Variable
class would have a container full of observers:
class Variable {
public:
std::vector<Observer*> observers; // warning: encapsulation omitted
void FireCallback(){
// assuming C++ 0x
for( auto it : observers ) {
(*it)->Callback( value );
}
}
If other functions need to be called on the same object, you may introduce a wrapper:
class OtherCaller: public Observer {
public:
MyObserver* obs;
virtual void callback( int v ) { obs->some_other_method( v ); }
}
And add it to the collection:
Variable var;
MyObserver m;
OtherCaller mo;
mo.obs = &m;
var.observers.push_back(&m);
var.observers.push_back(&mo);
var.FireCallback();
Upvotes: 2
Reputation: 96241
It depends on what your needs are here.
If you only have one callback function, and you always know its name, you might as well call it directly. It's simpler, easier to understand, and doesn't get extra variables involved.
Member function pointers would come in useful if you need the ability to call one of several callbacks depending on configuration: You would set the callback member function pointer to the actual callback you wish to call, and then that is used to select which callback to execute.
Upvotes: 1