Pass method as callback from one class to other class - c++

I have 2 class, I would like to pass a method from one to other by callback!
See that I also wish to hold the address of this method using void (*callBack)();
I'm used to do this in C, but I dont know how to do this in c++;
#include <iostream>
using namespace std;
class A
{
private:
void (*callBack)(); //to hold the address of the method
public:
A();
void setCallBack(void(*cB)());
void useCallBack();
};
A::A()
{
}
void A::setCallBack(void(*cB)())
{
callBack = cB;
}
void A::useCallBack()
{
callBack();
}
class B
{
private:
A * Aguy;
public:
B();
void someMethod();
void otherMethod();
};
B::B()
{
Aguy = new A();
}
void B::otherMethod()
{
Aguy->setCallBack(someMethod);
Aguy->useCallBack()
}
void B::someMethod()
{
cout << "Hello. I'm from class b" << endl;
}
int main()
{
B Bguy;
Bguy.otherMethod();
return 0;
}

The problem is that:
void (*callBack)();
This is not a pointer to a method. This is a pointer to a function.
To have a pointer to a method you need to specify the class the method is in.
void (B::*callBack)();
Then when you call it you need to call it via an object.
void A::useCallBack(B* b)
{
(b->*callBack)();
}
But this is probably not what you want.
What you really want is a wrapper that encapsulates all this.
I would take a look at std::function. This will allow you to wrap a method call and an object into a single object that you can then call.
std::function<void()> callback;
Just replace all your occurrences of void(*cB)() with std::function<void()> then you can bind an instance of the object to the method at the call point.
Aguy->setCallBack(std::bind(&B::someMethod, this));
This also allows you to seemly pass any normal function or functor as a callback.
void print()
{ std:cout << "It worked\n";
}
...
Aguy->setCallBack(&print);
struct Printer
{
void operator()() const
{
std::cout << "It worked with obejct\n";
}
}
...
Aguy->setCallBack(Printer());

If you need to pass member function pointers see the modified code. it uses modern c++ constructs.
#include <iostream>
#include <functional>
using namespace std;
class A
{
private:
typedef std::function<void()> some_void_function_type;
some_void_function_type f_;
public:
A();
void setCallBack(some_void_function_type f);
void useCallBack();
};
A::A()
{
}
void A::setCallBack(some_void_function_type f)
{
f_ = f;
}
void A::useCallBack()
{
f_();
}
class B
{
private:
A * Aguy;
public:
B();
void someMethod();
void otherMethod();
};
B::B()
{
Aguy = new A();
}
void B::otherMethod()
{
Aguy->setCallBack(std::bind(&B::someMethod, this));
Aguy->useCallBack();
}
void B::someMethod()
{
cout << "Hello. I'm from class b" << endl;
}
int main()
{
B Bguy;
Bguy.otherMethod();
return 0;
}

See c++ - <unresolved overloaded function type> for details.
To quote the answer:
In C++, member functions have an implicit parameter which points to
the object (the this pointer inside the member function). Normal C
functions can be thought of as having a different calling convention
from member functions, so the types of their pointers
(pointer-to-member-function vs pointer-to-function) are different and
incompatible. C++ introduces a new type of pointer, called a
pointer-to-member, which can be invoked only by providing an object.
Put static on someMethod:
class B
{
private:
A * Aguy;
public:
B();
static void someMethod();
void otherMethod();
};
void B::otherMethod() {
Aguy->setCallBack(B::someMethod);
Aguy->useCallBack(); // adding missing semicolon
}

Related

How to pass a member function as a parameter and execute list of methods on derived object

I want to create an array mapping integer values to member functions so that
(this->*actionMap[i])();
executes the method. In order to populate the array, I would like a method that sets elements of the array to the corresponding action.
I saw in an earlier question that it should use std::function and std::bind but I am not following the syntax, and I do not understand how to declare the array: How to properly pass member function as a parameter
Here is the M(non)WE
Note that I want a base class to be able to execute methods on the derived object.
#include <iostream>
using namespace std;
class Base;
typedef void (Base::*Action)();
class Base {
Action actions[3];
public:
void setAction(int a, Action act) {
actions[a] = act;
}
void f() { cout << "f"; }
void go() {
for (int i = 0; i < 3; i++)
(this->*actions[i])();
}
};
struct Derived : public Base {
void g() { cout << "g"; }
void h() { cout << "h"; }
Derived() {
setAction(1, f);
setAction(2, g);
setAction(1, h);
}
};
int main() {
Derived d;
d.go();
}
execute methods on the derived object.
So you have to have a handle to derived object when you execute the methods. And two of the methods are not in Base::, because they are not inside Base. They are inside Derived, so the pointers could be Derived::*, but that would make no sense and break the model I guess you want to have. I guess you could make your methods g h and f virtual inside Base. But that would again, defeat the purpose, I guess of an observer-like-ish pattern.
What you want to do, is basically easily solved with proper abstraction - std::function and std::bind.
#include <iostream>
#include <array>
#include <functional>
class Base {
std::array<std::function<void()>, 3> actions;
public:
void setAction(int a, std::function<void()> act) {
actions.at(a) = act;
}
void f() { std::cout << "f"; }
void go() {
for (auto&& action : actions) {
if (action) {
action();
}
}
}
};
struct Derived : public Base {
void g() { std::cout << "g"; }
void h() { std::cout << "h"; }
Derived() {
setAction(1, std::bind(&Derived::f, this));
setAction(2, std::bind(&Derived::g, this));
setAction(1, std::bind(&Derived::h, this));
}
};
int main() {
Derived d;
d.go();
}

pthread without static decelaration with class

Inside the class I declared the thread function. I used static keyword because with out static keyword it is not working with class.
But if the type of the function is static I could not able to access the member function and public variables of the class
#include <iostream>
#include <pthread.h>
using namespace std;
class Base{
private:
static void * fpga_read(void*); // Thread function
void foo_2();
public:
/* member variables */
void foo(void);
protected:
int b;
};
void Base::foo(void)
{
pthread_t id;
pthread_create(&id, NULL,fpga_read,NULL);
cout << "\nInside base class" << endl;
}
void * Base::fpga_read(void *p)
{
cout << "\nInside thread function " << endl;
// error: invalid use of member ‘Base::b’ in static member function
cout << "Value of B inside thread class" << b;
int b;
}
int main()
{
Base a;
a.foo();
pthread_exit(NULL);
return 0;
}
Any-body tell me how to use thread function with-out static keyword. so i can able to access all class variables.
You do not need any static member function. You can use the argument parameter of pthread_create and that stateless lambda functions decay to normal function pointers to make code which almost looks like what you actually wrote:
Godbolt link: https://godbolt.org/z/QIGNUX
#include <iostream>
#include <pthread.h>
class Base {
public:
Base(int state) noexcept : b{state} {}
void foo();
private:
int b;
void fpga_read() {
std::cout << "Value of B inside thread class" << b;
}
};
void Base::foo()
{
pthread_t thread;
pthread_create(&thread, nullptr, [](void* that) -> void* {
Base* this_ = static_cast<Base*>(that);
this_->fpga_read();
return nullptr;
}, static_cast<void*>(this));
pthread_join(thread, nullptr);
}
pthread_create, like all OS-specific thread creation APIs (CreateThread etc in Windows) has a "void*" parameter to pass to the thread function.
You can use this to pass a pointer to your class
class A
{
void ThreadToUse() {}
static void Thread2(void* p)
{
A* a = (A*)p;
p->ThreadToUse();
}
void foo()
{
pthread_create(&A::Thread2,(void*)this);
}
};
That said, you can use C++11 std::thread with the same functionality as well in a standard way:
void foo()
{
std::thread t(&A::Thread2,this);
}

Calling a class member function from a thread using pthread_create

Below is the code
#include <iostream>
#include <pthread.h>
using namespace std;
class Base
{
private:
public:
void *threadCall1( void * value)
{
cout<<"inside threadCall1"<<endl;
}
protected:
};
class Derived
{
private:
public:
void *threadCall2 ();
protected:
};
void *Derived::threadCall2()
{
cout<<"inside threadCall2"<<endl;
}
int main ()
{
int k = 2;
pthread_t t1;
cout<<"inside main"<<endl;
Base *b = new Base();
pthread_create(&t1,NULL,&b->threadCall1,(void *)k);
return 0;
}
Error
main.cc: In function int main()': main.cc:46: error: ISO C++ forbids
taking the address of a bound member function to form a pointer to
member function. Say&Base::threadCall1' main.cc:46: error: cannot
convert void*(Base::*)(void*)' tovoid*()(void)' for argument 3'
toint pthread_create(pthread_t*, const pthread_attr_t*,
void*()(void), void*)'
I agree C++ forbids this call but is there any way I can call a class member function using posix thread
You can do this via a function that dispatches the work accordingly:
#include <iostream>
#include <pthread.h>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
void* thread_adapter(void* obj) {
Base* p = static_cast<Base*>(obj);
p->work();
return nullptr;
}
int main() {
Derived d;
pthread_t thread;
pthread_create(&thread, nullptr, thread_adapter, &d);
pthread_join(thread, nullptr);
}
Live example
pthread_create accepts a pointer to arbitrary data for the thread function. Pass the address of your object, and use a forwarding function such as the thread_adapter defined above. Inside the adapter function, you can static_cast the argument back to a Base* inside your thread function and invoke the member function as desired.
However, you may want to look into the std::thread library, which supports such operations in a more natural way:
#include <iostream>
#include <thread>
struct Base {
virtual void work() {
std::cout << "Base::work()\n";
}
virtual ~Base() {}
};
struct Derived : public Base {
void work() override {
std::cout << "Derived::work()\n";
}
};
int main() {
Derived d;
std::thread t(&Base::work, d);
t.join();
}
Live example
There's no such thing as &b->threadCall1. Fortunately, pthread allows you to pass a void ptr to the class (the one you're filling with k). Pass b as this void ptr to a global (or static member) function that simply calls b->threadCall1(); then move k to an attribute of Base instead of an argument of Base::threadCall1().
You cannot use pointer to member function as thread routine. Consider to use thead context structure to pass need information to the thead routine:
struct thread_context {
Base* object;
void (Base::*func)(void*);
};
void *thread_routine(void *arg) {
thread_context* context = static_cast<thread_context*>(arg);
context->object->(*context->func)(nullptr);
...
}
...
thread_context context = {
b1,
&Base::threadCall1
};
pthread_create(&t1,NULL,&thead_routine, &context);

How to get class member function pointer

For one class I want to store some function pointers to member functions of another class. I am trying to return a class member function pointer. Is it possibile?
class one{
public:
void x();
void y();
};
typedef void(one::*PF)(void);
class two :public one{
public:
virtual PF getOneMethodPointer();
};
class three : public two{
std::vector<PF> pointer_to_function;
PF getOneMethodPointer();
pointer_to_function.push_back(getOneMethodPointer())? //how to get method x from class one?
};
In C++11/14, you can always use std::function wrapper to avoid writing unreadable and old C-style function pointers. Here's a simple program with this approach:
#include <iostream>
#include <functional>
using namespace std;
class one {
public:
void x() { cout << "X called" << endl; }
function<void()> getOneMethodPointer();
};
class two : public one {
public:
function<void()> getOneMethodPointer() {
return bind(&one::x, this);
}
};
int main()
{
two* t = new two();
t->getOneMethodPointer()();
delete t;
return 0;
}
As you can see, there's also std::bind used to bind method with std::function. First argument is a reference to the x() method and the second one specifies to which concrete (instantiated) object the pointer is meant to point. Note, that if you say to the st::bind "hey, bind me x() method from one class", it still doesn't know where it is. It knows that - for instance - x() method in this object can be found 20 bytes next to its beginning. Only when you add that it is from for example two* t; object, the std::bind is able to locate the method.
EDIT: Answering to your questions in comments: below code shows an example with virtual getMethodPointer() method:
#include <iostream>
#include <functional>
using namespace std;
class one {
public:
void x() { cout << "X called (bound in one class)" << endl; }
void y() { cout << "Y called (bound in two class)" << endl; }
virtual function<void()> getMethodPointer() {
return bind(&one::x, this);
}
};
class two : public one {
public:
virtual function<void()> getMethodPointer() {
return bind(&one::y, this);
}
};
int main()
{
one* t_one = new one();
one* t_two = new two();
t_one->getMethodPointer()();
t_two->getMethodPointer()();
delete t_one;
delete t_two;
return 0;
}
The C++ syntax for it is this:
class two: public one{
virtual PF getOneMethodPointer(){
return &one::x;
}
};
[Live example]

Assign pointer to a function the address of a pointer to function object

Is it possible in C++?
For example I have a pointer to a function that takes no parameters and its return type is void:
void (*f)();
and and a function object:
class A
{
public:
void operator()() { cout << "functor\n"; }
};
Is it possible to assign to f the address of an A object? And when I call f() to call the A functor?
I tried this but it doesn't work:
#include <iostream>
using namespace std;
class A
{
public:
void operator()() { cout << "functorA\n"; }
};
int main()
{
A ob;
ob();
void (*f)();
f = &ob;
f(); // Call ob();
return 0;
}
I get C:\Users\iuliuh\QtTests\functor_test\main.cpp:15: error: C2440: '=' : cannot convert from 'A *' to 'void (__cdecl *)(void)'
There is no context in which this conversion is possible
Is there any way to achieve this?
You can't do it in the way you've specified, because:
operator() must be a nonstatic function (standards requirement)
a pointer to a non-static function must have an implicit parameter - the pointer to the class instance
your call to f() does not give any indication on which instance of the object A your function is called
Using C++11 and std::function, as Stephane Rolland pointed out, may do the trick - you'll be specifying the pointer to the object in the binding:
std::function<void(void)> f = std::bind(&A::operator(), &ob);
(See question on using std::function on member functions)
If you use C++11, could use std::function
#include <functional>
std::function<void()> f;
int main()
{
A ob;
ob();
f = ob; // f refers to ob
f(); // Call ob();
return 0;
}
Yes it's kind of possible using a C++1/C++0x feature, but to achieve this you should use the std::function which can address to the two types, functions and object functions.
#include <functional>
class A
{
public:
void operator()() { }
};
int main()
{
std::function<void(void)> aFunction;
A ob;
aFunction = ob;
// or as another user said
// aFunction = std::bind(&A:operator(), &ob);
aFunction();
void (*f)();
aFunction = f;
aFunction();
return 0;
}
and if you're stuck with C++03, you could play with std::mem_fun and std::ptr_fun
How about some workaround like this:
Basically you want to have a common way of calling member functions and functions. Then maybe you could create a wrapper that would represent a generic pointer to either a function or member function. Let's say you have Base class and you want to be able to invoke operator() of all derived classes. Then you also have a function() that you want to invoke as well:
class Base
{
public:
virtual void operator()() = 0;
};
class A : public Base
{
public:
void operator()(){ std::cout << "A()" << std::endl; }
};
void function()
{
std::cout << "function" << std::endl;
}
If you create an wrapper that allows you to construct your custom pointer (MyFncPtr):
typedef void (Base::*BaseFncPtr)();
typedef void (*FncPtr)();
class MyFncPtr
{
public:
MyFncPtr(FncPtr f) : fnc(f), baseObj(NULL), baseFnc(NULL) { }
MyFncPtr(BaseFncPtr fPtr, Base* objPtr) : baseFnc(fPtr), baseObj(objPtr), fnc(NULL) { }
void invoke()
{
if (baseObj && baseFnc)
(baseObj->*baseFnc)();
else if (fnc)
fnc();
}
private:
BaseFncPtr baseFnc;
Base* baseObj;
FncPtr fnc;
};
you could achieve it like this:
A a;
MyFncPtr myPtr(&Base::operator(), &a);
myPtr.invoke();
MyFncPtr myPtr2(function);
myPtr2.invoke();
outputs:
A()
function
Hope this helps :)