Callback function C++ - c++

I'm having a great deal of problems trying to make a callback system. I want to pass a function to another class's function to receive data.
I want ExampleClass to call SeperateThread::operate, and I want SeperateThread::operate to be able to call ExampleClass::updateNumber(int) to return a value. I've been trying for hours with various function pointers etc but can't seem to get it to work.
SeperateThread is another thread so it doesn't block the main thread that ExampleClass is running in, but when SeperateThread has done it's calculations, I need to return the value to ExampleClass.
If that makes sense? Here's a run down of what I'm trying to do. In this example, I want SeperateThread::operate to call ExampleClass::updatenumber(15);...
class ExampleClass
{
public:
ExampleClass()
{
int numberToPass = 10;
// call SeperateThread::operate and pass value and updatenumber function as pointer
thread.operate(numberToPass, *updatenumber(int number));
}
~ExampleClass();
void updatenumber(int number)
{
// Do some stuff to the number passed to this function
}
private:
SeperateThread thread;
}
class SeperateThread
{
public:
SeperateThread();
~SeperateThread();
void operate(int number, &FunctionToCallBack)
{
// Do some calculations (result 5 for example purposes)
int result = numberToPass + 5;
// Call the callback function and pass result int
FunctionToCallBack(result);
}
}

There are two issues here:
1. A Callback Function Is Not Enough
You'll need both an address for the code to call back, and the identity of the object on which the code should operate. The idiomatic C++ way to do this is to encapsulate this in an object:
class SeparateThread {
public:
class Callback {
public:
virtual void ThreadDone(int result) const = 0;
virtual ~Callback() {}
};
void operate(int number, const Callback & callback)
{
// Calculate result
callback.ThreadDone(result);
}
};
ExampleClass can then either inherit privately from SeparateThread::Callback and implement ThreadDone() or define a separate callback class:
class ExampleClassThreadCallback : public SeparateThread::Callback {
public:
ExampleClassThreadCallback(ExampleClass * obj) : fObj(obj) {}
void ThreadDone(int result) const override {
fObj.updatenumber(result);
private:
ExampleClass * fObj;
}
};
You then simply call the thread as:
thread.operate(number, ExampleClassThreadCallback(this));
2. Concurrency
In a design like this, where your class gets updated from a separate thread, you are likely to run into concurrency issues, so you'll have to design appropriate mechanisms to make sure that this updating does not cause problems.

There is something important about pointing to a class member function, you have to keep in mind that a function pointer is just a regular pointer but instead of a value it points to a function, but in a class there is a special hidden variable this which makes it tricky.
One of the main problems here is that there is no pointer to the object since that would mean that you point to a function that exists within a specific object but it doesn't it just a plain function that contains this as a parameter.
thread.operate(numberToPass, *updatenumber(int number));
Here you call a function that is in another class and overall you never pass a pointer like this, it should be just the function's name since C will recognize that you want to pass it as a pointer. Generally the workaround would be to make the function static to avoid the problem with the this pointer.
One possible workaround would be to hold onto the class object and somehow hackishly call that function where you manually pass the this of the original object ( ExampleClass ).
You didn't say much about your design, but the fact that you put the source into the same field means that these classes "know" each other so why don't you just pass the class object and call the function that way like:
class BaseClass
{
public:
BaseClass() {}
~BaseClass() {}
virtual void updatenumber(int number)=0; // pure virutal method, you MUST implement this in the subclasses!
}
class ExampleClass : public BaseClass
{
public:
ExampleClass()
{
int numberToPass = 10;
// call SeperateThread::operate and pass value and updatenumber function as pointer
thread.operate(numberToPass, this);
}
~ExampleClass();
// this is now a virtual method
void updatenumber(int number)
{
// Do some stuff to the number passed to this function
}
private:
SeperateThread thread;
}
class SeperateThread
{
public:
SeperateThread();
~SeperateThread();
void operate(int number,BaseClass* ObjectToCallBack)
{
// Do some calculations (result 5 for example purposes)
int result = numberToPass + 5;
// Call the callback function and pass result int
// Note that here that this points to the BaseClass pointer but it can be a subclass of it effectively hiding it's "unneded members" at this specific point
ObjectToCallBack->updatenumber(result);
}
}
In case you want to hide the implementation you can just use a pure virtual class and pass that type of pointer to the SeperateThread class.
Edit : updated my example to use a base class.

There is a way to pass a member of a specific class instance to another function whether in a thread or not. If the callback is a member you need to wrap it together with the class instance you want the callback to affect.
template<typename T, typename F, typename R>
struct callback
{
callback(T cthis, F func) : _this(cthis), _func(func) { }
void operator()(R result)
{
(_this->*_func)(result);
}
T _this;
F _func;
};
class SeperateThread
{
public:
SeperateThread() { }
~SeperateThread() { }
template<typename T, typename F, typename R>
void operate(int number, callback<T,F,R> cb)
{
// Do some calculations (result 5 for example purposes)
int result = number + 5;
// Call the callback function and pass result int
cb(result);
}
};
class ExampleClass
{
public:
ExampleClass()
{
int numberToPass = 10;
// call SeperateThread::operate and pass value and updatenumber function as pointer
thread.operate(numberToPass, callback<ExampleClass * const, void (ExampleClass::*)(int), int>(this, &ExampleClass::updatenumber) );
}
~ExampleClass() { }
void updatenumber(int number)
{
// Do some stuff to the number passed to this function
printf("Result is %d\n", number);
}
private:
SeperateThread thread;
};
void test()
{
ExampleClass a;
}
The above will print: Result is 15.
Please note that I did not address the synchronization issues due to multithreading.
If 'updatenumber' is called by more than one thread, and your code inside it accesses other data members, then you need to serialize it by adding a mutex lock at the beginning and unlock it before returning. Best is to use std::mutex if you have C++11 compiler, or do this within a small struct, locking in the constructor and unlocking in the destructor. Then you just create one such instance immediately on updatenumber() entry.

Related

Replacing a design to use capturing lambda only

I am trying to generalize a callback mechanism.
I need two things for that:
Calling it in a general matter: void call() - that I was able to manage
I mean that everyone can get a void call() function, and I can even (easily) store them in an array. They are all of the same type.
class Function{
public:
virtual void call()=0;
};
template<typename T>
class TemplatedFunction : public Function{
public:
int (T::*m_fkt)();
T* m_obj;
TemplatedFunction(T* obj, int (T::*fkt)()):m_fkt(fkt),m_obj(obj){}
// Can also set here a [&](){ f(Args...args) } that will capture the callback arguments, and call it via call(). f being the std::function created for the callback.
void call(){
(m_obj->*m_fkt)();
}
};
Set (register callback) in a general matter: here I got lost...
My callbacks are statically allocated.
I saw this great option, but my only option is using a capturing lambda.
( no bind, or tuple.. )
This option is great as I can store an array of EventHandler that basically will differ by the ID of a message I will get. Unfortunately I can't use new. (I use an in place static allocation for lambda)
class EventHandler{
public:
Function* m_func=nullptr;
template<class T>
void SetCallbackFunction(T* obj, void (T::*mem_fkt)()){
if(m_func != nullptr)
delete m_func;
m_func = new TemplatedFunction<T>(obj,mem_fkt); // can't use it.
}
void TestCallback(){
if(m_func != nullptr)
m_func->call();
}
~EventHandler(){
if(m_func != nullptr)
delete m_func;
}
};
As of my callbacks are statically allocated in advanced, containing the option to call, but not to set.
I know that there are many designs available, but I am limited to using a capturing lambda only with an std::function replacement to store it.
My goal is to pass a single type EventHandler to all my messages, without the need to template the messages, so I will be able to store them in a std::array<Msg_t>
here how I want it to look in the end:
// Statically allocated callbacks that have general `void call()`
//Function* m_func_to_run_callback1 = TemplatedFunction<> Callback1();
// Function* m_func_to_run_callback2 = TemplatedFunction<> Callback2();
int main()
{
EventHandler eh, eh1;
Foo foo; // some class
Foo2 foo2; // some other class
eh.SetCallbackFunction(&foo, &Foo::bar, m_func_to_run_callback1 ) ;
eh1.SetCallbackFunction(&foo2, &Foo2::bar2, m_func_to_run_callback1) ;
return 0;
}
I think that what I am missing is :
class Function{
public:
virtual void call()=0;
virtual void set(void*) = 0; // void* being the callback function
};

How to pass lambda function by pointer?

I am a new in c++ maybe I miss something, but actually what I need to do is: I have a class that processing something in other thread, during this processing I need that it invoke a callback for progress.
How I see I can do it, I need to declarate pointer (maybe shared_ptr) for my callback function as a class member, than I have a setter in order to pass pointer to callback and then I can use it. A few issues here are how to pass it correctly? How to invoke pointer on function?
My implementation is:
class RobocopyCopy
{
//Public members
public:
typedef std::function<void(int)> TVoidIntCallback;
RobocopyCopy * set_monitoring_done_callback(TVoidIntCallback monitoring_done_callback)
{
m_pMonitoring_done_callback = &monitoring_done_callback;
return this;
}
//This method executes in background
void execute()
{
...
//and here I need to invoke my callback
(TVoidIntCallback *)m_pMonitoring_done_callback(777); //but this is not correct
private:
TVoidIntCallback * m_pMonitoring_done_callback;
...
}
and final implementation of this should be like this (I think) :
RobocopyCopy robocopy;
robocopy.set_monitoring_done_callback([this](int my_progress) {
printf("Progress is :: %d", my_progress);
});
So, as I mentioned above questions is :
how to pass this function callback as a lambda and save in Robocopy class as a pointer
How to invoke this function correctly, because this (TVoidIntCallback *)m_pMonitoring_done_callback(777); doesn't work.
I am using VC++ I hope this code will be successful for you.
class RobocopyCopy
{
typedef std::function<void(int)> TVoidIntCallback;
TVoidIntCallback evnt;
public:
RobocopyCopy* set_monitoring_done_callback(TVoidIntCallback
monitoring_done_callback)
{
//set callBack function from out side.
evnt = monitoring_done_callback;
return this;
}
void execute() {
//invoke your callBack
evnt(1000000);
}
};
int main()
{
RobocopyCopy obj;
obj.set_monitoring_done_callback([](int data) {
std::cout << data << "\n";
})->execute();
}

How to invoke pointer to member function from static member function?

I need to get a member function called by a standard function pointer, so I tried to abstract things like this:
class Sample {
public:
virtual void doSomething(void) = 0;
};
class A : public Sample {
void doSomething(void); // details omitted
};
class B : public Sample {
void doSomething(void); // details omitted
};
class Executor {
public:
Executor(Sample *sample)
: func(&sample->doSomething)
{
}
static void *execute(void *data) {
Executor *pX = data;
(pX->*func)(); // error invalid access of func from static function
(pX->*pX->func)(); // error pointer to member type 'void (Sample::)()'
// incompatible with object type 'Executor'
}
private:
void (Sample::*func)(void);
};
int main(void) {
A myA;
B myB;
Executor x0(&myA);
Executor x1(&myB);
externallyInvoke(&Executor::execute, &x0);
externallyInvoke(&Executor::execute, &x1);
}
externallyInvoke is a Linux system call, which takes a function pointer and a data pointer.
I'd like to use a static member function together with a this-pointer as data.
... and I don't want classes like A or B to have static members. So my idea was to create an interface like class Sample, that gets extended by A and B.
My problem is that I don't know how to invoke the pointer to member function from inside the Executor::execute function.
The problem is that you need two objects inside execute - one is the instance of Executor which will supply func, and the other is an instance of (a class derived from) Sample on which func will be invoked. So you have to store the object inside Executor, not the function:
class Executor {
public:
Executor(Sample *sample)
: obj(sample)
{
}
static void *execute(void *data) {
Executor *pX = static_cast<Executor*>(data);
pX->obj->doSomething();
}
private:
Sample *obj;
};
int main() { // note that `void main()` is not legal C++
A myA;
B myB;
Executor x0(&myA);
Executor x1(&myB);
externallyInvoke(&Executor::execute, &x0);
externallyInvoke(&Executor::execute, &x1);
}
A pointer to member function (such as your original void (Sample::*func)()) identifies a function within a class, but does not store the object. You'd still need to provide one to call the function.
If you want to interact with an external system call, you basically have to reinvent std::function yourself. No problem, here at Stack Overflow we're the masters of reinventing existing technology. So...
First, the interface:
struct FunctionStateBase
{
virtual ~FunctionStateBase() {}
virtual void Invoke() = 0;
};
extern "C" void InvokeAndDelete(void * data)
{
auto state = static_cast<FunctionStateBase *>(data);
state->Invoke();
delete state;
}
Here's how you use it:
externallyInvoke(&InvokeAndDelete, MakeFunction(&A::doSomething, &myA));
Now we need to implement MakeFunction:
template <typename> struct FunctionState;
template <typename C, typename R>
struct FunctionState<R (C::*)()> : FunctionStateBase
{
R (C::ptmf_*)();
C * obj_;
FunctionState(R (C::ptmf*)(), C * obj) : obj_(obj), ptmf_(ptmf) {}
virtual void Invoke() { (C->ptmf_)(); }
};
template <typename C, typename R>
FunctionState<R (C::*)()> MakeFunction(R (C::*ptmf)(), C * obj)
{
return new FunctionState<R (C::*)()>(ptfm, obj);
}
At this point we're managing the life time of the function wrapper manually, and note that InvokeAndDelete actually takes ownership of the function state. In proper C++, we would wrap the entire system call invocation in a class that would encapsulate the lifetime management internally.
You can add further specializations for member functions that take arguments; you just need to store a copy of the arguments in the state.
You'll need to also pass an instance ofSample on which to call the function (since it's a pointer to a member of Sample). There's a few ways to bring the instance along. You could make it a member of Executor, pass a std::pair* as data or you could combine the function pointer and the instance as a functor. Here's a lamda based approach for the latter. Lamda has the advantage of being more versatile. It's possible to do much more than just call one member of one class. As a bonus, this approach does not avoid visibility rules, although that means doSomething may not be private (or it must be called through the parent pointer).
template<class F>
class Executor {
F f;
public:
Executor(F f): f(f){}
static void *execute(void *data) {
Executor<F> *pX = static_cast<Executor<F>*>(data);
pX->f();
return this; // not quite sure what you intend to return, but just to make this a well formed function...
}
};
int main() {
A myA;
B myB;
auto callback0 = [myA]{
myA.doSomething();
};
auto callback1 = [myB]{
myB.doSomething();
};
Executor<decltype(callback0)> x0(callback0);
Executor<decltype(callback1)> x1(callback1);
externallyInvoke(&Executor::execute, &x0);
externallyInvoke(&Executor::execute, &x1);
}

method pointer and inheritance // kind of strategy pattern (C++)

In my design, there is a class which reads information from file. The read info represents a job (for simplicity, it's an integer, which is "job id"). The file reader class can accept objects which can handle such a job. Now my idea was, to make an Interface, e.g. "IJobHandler" which has a pure virtual function "DoJob()" and then you can call something like
FileReader fr;
Class1 c1; // has a base class IAcceptor with virtual method HandleJobId()
Class2 c2; // has a base class IAcceptor with virtual method HandleJobId()
fr.Register(c1);
fr.Register(c2);
fr.doJob(1); // calls c1.HandleJobId()
fr.doJob(2); // class c2.HandleJobId()
This would work fine. But what happens, if some class can handle two or more job ids? But there is only one method which this class can implement (HandleJobId()). Wouldn't the following be nice:
fr.Register(c1, c1::Handle_1()) or something like that?
Maybe my intention is not very clear right now. But you will se it on the bigger code example below. Sorry for the big code block, but I don't know how to explain it that exactly...
class IAcceptable
{
public:
// interface; implementors should return map of job-ids (int)
// and a kind of pointer to a method which should be called to
// handle the job.
virtual std::map<int, SOME_KIND_OF_FUNCTION_POINTER> GetJobIds() const = 0;
};
class Class12 : public IAcceptable
{
public:
void Handle_1(){} // method to handle job id 1
void Handle_2(){} // method to handle job id 2
virtual std::map<int, SOME_KIND_OF_FUNCTION_POINTER> GetJobIds() const
{
std::map<int, SOME_KIND_OF_FUNCTION_POINTER> intToMethodMap;
// return map, which says: "I can handle job id 1, by calling Handle_1(), so I give you c12 pointer to this method"
// (same thing for job id 2 and Handle_2())
intToMethodMap.insert(std::pair<int, SOME_KIND_OF_FUNCTION_POINTER>(1, POINTER_TO_Handle_1);
intToMethodMap.insert(std::pair<int, SOME_KIND_OF_FUNCTION_POINTER>(2, POINTER_TO_Handle_2);
return intToMethodMap;
}
};
class Class34 : public IAcceptable
{
void Handle_3(){} // method to handle job id 3
void Handle_4(){} // method to handle job id 4
virtual std::map<int, SOME_KIND_OF_FUNCTION_POINTER> GetJobIds() const
{
std::map<int, SOME_KIND_OF_FUNCTION_POINTER> intToMethodMap;
// return map, which says: "I can handle job id 3, by calling Handle_3(), so I give you c12 pointer to this method"
// (same thing for job id 4 and Handle_4())
intToMethodMap.insert(std::pair<int, SOME_KIND_OF_FUNCTION_POINTER>(3, POINTER_TO_Handle_3);
intToMethodMap.insert(std::pair<int, SOME_KIND_OF_FUNCTION_POINTER>(4, POINTER_TO_Handle_4);
return intToMethodMap;
}
};
class FileReader
{
public:
// register an IAcceptable
// and add its handlers to the local list
void Register(const IAcceptable& acc)
{
m_handlers.insert(acc.GetJobIds());
}
// if some job is to do, search for the job id and call
// the found function
void doSomeJob(int i)
{
std::map<int, SOMEFUNCTION>::iterator specificHandler = m_handlers.find(i);
// call here (specificHandler->second)()
}
private:
std::map<int, SOMEFUNCTION> m_handlers;
};
int main()
{
Class12 c12; // can handle job id 1 and 2
Class34 c34; // can handle job id 3 and 4
FileReader fr;
fr.Register(c12);
fr.Register(c34);
fr.doSomeJob(1); // should lead to this call: c12->Handle_1()
fr.doSomeJob(2); // c12->Handle_2();
fr.doSomeJob(3); // c34->Handle_3();
fr.doSomeJob(4); // c34->Handle_4();
}
Well, maybe the design is my problem and someone can give me a hint how to make it better :)
Here's a complete example:
class IAcceptable;
class DelegateBase
{
public:
virtual void Call() = 0;
};
template <class Class> class Delegate: public DelegateBase
{
public:
typedef void (Class::*Function)();
Delegate(Class* object, Function f): func(f) {}
virtual void Call() { (object->*func)(); }
private:
Class* object;
Function func;
};
class IAcceptable
{
public:
// interface; implementors should return map of job-ids (int)
// and a kind of pointer to a method which should be called to
// handle the job.
virtual std::map<int, DelegateBase*> GetJobIds() = 0;
};
class Class12 : public IAcceptable
{
public:
void Handle_1(){} // method to handle job id 1
void Handle_2(){} // method to handle job id 2
virtual std::map<int, DelegateBase*> GetJobIds()
{
std::map<int, DelegateBase*> intToMethodMap;
// return map, which says: "I can handle job id 1, by calling Handle_1(), so I give you c12 pointer to this method"
// (same thing for job id 2 and Handle_2())
intToMethodMap.insert(std::pair<int, DelegateBase*>(1, new Delegate<Class12>(this, &Class12::Handle_1)));
intToMethodMap.insert(std::pair<int, DelegateBase*>(2, new Delegate<Class12>(this, &Class12::Handle_2)));
return intToMethodMap;
}
};
class Class34 : public IAcceptable
{
void Handle_3(){} // method to handle job id 3
void Handle_4(){} // method to handle job id 4
virtual std::map<int, DelegateBase*> GetJobIds()
{
std::map<int, DelegateBase*> intToMethodMap;
// return map, which says: "I can handle job id 3, by calling Handle_3(), so I give you c12 pointer to this method"
// (same thing for job id 4 and Handle_4())
intToMethodMap.insert(std::pair<int, DelegateBase*>(3, new Delegate<Class34>(this, &Class34::Handle_3)));
intToMethodMap.insert(std::pair<int, DelegateBase*>(4, new Delegate<Class34>(this, &Class34::Handle_4)));
return intToMethodMap;
}
};
class FileReader
{
public:
// register an IAcceptable
// and add its handlers to the local list
void Register(IAcceptable& acc)
{
std::map<int, DelegateBase*> jobIds = acc.GetJobIds();
m_handlers.insert(jobIds.begin(), jobIds.end());
}
// if some job is to do, search for the job id and call
// the found function
void doSomeJob(int i)
{
std::map<int, DelegateBase*>::iterator specificHandler = m_handlers.find(i);
specificHandler->second->Call();
}
private:
std::map<int, DelegateBase*> m_handlers;
};
int _tmain(int argc, _TCHAR* argv[])
{
Class12 c12; // can handle job id 1 and 2
Class34 c34; // can handle job id 3 and 4
FileReader fr;
fr.Register(c12);
fr.Register(c34);
fr.doSomeJob(1); // should lead to this call: c12->Handle_1()
fr.doSomeJob(2); // c12->Handle_2();
fr.doSomeJob(3); // c34->Handle_3();
fr.doSomeJob(4); // c34->Handle_4();
return 0;
}
To call a member function we need an object; so your maps should contain not simply method pointers, but something that can encapsulate a complete call: an object + a method pointer. That something is Delegate here.
To make sure that the method is called correctly even if it's defined in a subclass, we need to store both the derived object and the method pointer type-correctly (no casting). So we make Delegate a template, with the derived class as its parameter.
This means that delegates based on methods of different subclasses are incompatible, and cannot be put into a map. To work around this we introduce a common base class, DelegateBase, and the virtual function Call(). Call() can be called without knowing the exact type of stored object / method, and it will be dispatched to a type-correct implementation. Now we can store DelegateBase* pointers in the map.
Also check out boost::function and boost::bind, they provide a generalization for the above, and I think they could also be used to your purposes.
There are several solutions to this sort of problem.
If you have a class which can handle several different jobs, in separate
functions, the simplest solution is to wrap it, several types, e.g.:
class JobsOneAndTwo
{
public:
void doJobOne();
void doJobTwo();
};
class JobOne : public AbstractJob, JobsOneAndTwo
{
public:
virtual void doJob() { doJobOne(); }
};
class JobTwo : public AbstractJob, JobOneAndTwo
{
public:
virtual void doJob() { doJobTwo(); }
};
If this occurs often in the set of jobs, you can create a template (over
two or moer member function pointers) to generate the individual wrapper
functions.
Alternatively, you can dispatch on a data member of the class:
class JobOneAndTwo : public AbstractJob
{
int myJob;
public:
JobOneAndTwo(int id) : myJob( id ) {}
void JobOne();
void JobTwo();
virtual void doJob()
{
switch ( myJob ) {
case 1:
JobOne();
break;
case 2:
JobTwo();
break;
}
};
In this case, you instantiate the class twice, each time passing a
different argument to the constructor.
In most of the cases I've seen, when one class can handle two jobs, it's
because the two jobs differ only in some parameters; this is really just
a variant on the second solution above, except that you don't switch to
call different member functions, you simply use the parameters (passed
into the constructor) in the basic function.
More generally, don't forget that your concrete job classes can have
data, and their behavior can be modified by such data. And that you can
register multiple instances of a single class, with different data.
So you say that you have many handlers, each of which can handle an arbitrary number of job IDs, and you want to register an arbitrary number of handlers and let all of them which apply handle a given job.
To that end, let every handler implement this interface:
struct Handler
{
virtual bool canHandle(job_id_t id) const = 0;
virtual void doJob(job_it_t id) = 0;
};
To register a handler, simply store a pointer in a container:
std::vector<Handler*> handlers;
Then, if you need to do a job, iterate the container and dispatch:
handleJob(job_it_t id)
{
for (std::vector<Handler*>::iterator it = handlers.begin(), end = handlers.end(); it != end; ++it)
{
if ((*it)->canHandle(id))
(*it)->doJob(id);
}
}
typedef void (IAccaptable::*SOME_KIND_OF_FUNCTION_POINTER)();
...
Register(1, (SOME_KIND_OF_FUNCTION_POINTER)(&Class12::Handle1));
Warning: this C-style cast will only work with single inheritance. (Well, actually the cast would compile just fine with multiple inheritance too, but when calling (derivedObject->*funcPtr)() with a funcPtr that points at a member function of a non-first base class, then it would be called without the derivedObject pointer having been properly adjusted to point at the proper subobject belonging to that base, most probably resulting in a crash.)
A better, but more complicated solution would be to register small caller objects instead of member function pointers. When calling the handler functions, these caller objects could appropriately cast the target object.
class CallerBase
{
public:
virtual void Call(Base* object) = 0;
};
template <class Derived>
struct Caller: public CallerBase
{
public:
typedef void (Derived::*Function)();
Caller(Function f): func(f) {}
virtual void Call(Base* object)
{
Derived* derived = static_cast<Derived*>(object);
(derived->*func)();
}
private:
Function func;
};
Register(1, new Caller<Derived>(&Derived::F));
Then your map would contain CallerBase* pointers, and once you find the proper caller, you'd do caller->Call(object). If object in this call is a Derived*, then it will be implicitly cast to Base*, but the virtual Caller<Derived>::Call() function will cast it back to Derived* before actually calling the method.
Method pointers can be a lot of fun.
I don't want to self promote myself but check out my guide on them I wrote back in school.
http://nicolong.com/code-examples/menu-object-tutorial
Might help a little.

static thread function access non-static class member in C++

Class Test{
int value;
static void* thread_func(void* args){
value++;
}
void newthread(){
pthread_create(&thread_func,...);
}
}
I'm trying to create a thread in Class Test. Therefore compiler forces me to make thread_func static. However I cannot access the non-static member "value" anymore. It says:
invalid use of member 'Class::value' in static member function
Is there a way around it?
However I cannot access the non-static
member "value" anymore.
That is because static function in your class doesn't have (and cannot have ) this pointer. All you need to pass the pointer to your Test object to pthread_create() function as fourth argument, and then do this:
static void* thread_func(void* args)
{
Test *test = static_cast<Test*>(args);
test->value++;
//write return statement properly
}
However, if you're doing too many things in thread_func() that require access to Test class members at many places, then I would suggest this design:
//this design simplifies the syntax to access the class members!
class Test
{
//code omitted for brevity
static void* thread_func(void* args)
{
Test *test = static_cast<Test*>(args);
test->run(); //call the member function!
//write return statement properly
}
void run() //define a member function to run the thread!
{
value++;//now you can do this, because it is same as 'this->value++;
//you do have 'this' pointer here, as usual;
//so access other members like 'value++'.
}
//code omitted for brevity
}
Better design : define a reusable class!
Even better would be to define a reusable class with pure virtual function run() to be implemented by the derived classes. Here is how it should be designed:
//runnable is reusable class. All thread classes must derive from it!
class runnable
{
public:
virtual ~runnable() {}
static void run_thread(void *args)
{
runnable *prunnable = static_cast<runnable*>(args);
prunnable->run();
}
protected:
virtual void run() = 0; //derived class must implement this!
};
class Test : public runnable //derived from runnable!
{
public:
void newthread()
{
//note &runnable::run_thread
pthread_create(&runnable::run_thread,..., this);
}
protected:
void run() //implementing the virtual function!
{
value++; // your thread function!
}
}
Looks better?
Let thread_func take a pointer to an object of the class as argument.
static void* thread_func(void* pThis)
{
static_cast<Test*>(pThis)->value++;
}
In case, this method wants to take some other information as well, put both in another struct/class and pass that in.