I'm trying to figuring out how Callbacks (pointers to functions) work. I have the following problem (example):
A class TMySerialReader reads the serial input with a while(true) loop. If something is read, a callback should be sent, i.e. a function should be called. Since I don't want this callback to be linked to a specific function, I want to use a pointer to a function (readCallback).
The second class TMyClass starts the reading process, sets the callback pointer and also contains the function that is called (ProcessRead).
The problem is now, how can I set the callback pointer? I tried caller->readCallback = &TMyClass::ProcessRead;
but this don't work. How can I do this?
The way you have it defined... readCallback is a pointer to a global function, not to a TMySerialReader member function:
1 2 3 4 5 6 7 8 9 10 11 12 13
class TMySerialReader
{
public:
void (TMySerialReader::*readCallback)();
// to assign it
TMySerialReader *caller = new TMySerialReader;
caller->readCallback = &TMyClass::ProcessRead;
// to call it
(this->*readCallback)(); // you might be able to omit the *this -- I'm not sure. Try it and see
The assignment is still wrong (invalid cast from type ‘void (TMyClass::*)()’ to type ‘TMySerialReader*’).
Shouldn't it be 'void (TMyClass::*readCallback)();' to match the assignment? But then TMySerialReader has to know TMyclass, and I don't want that. And also the "(this->*readCallback)()" don't work.
You need to note that a pointer to a non-static member function needs an object to operate on.
This means that you cannot do this:
1 2 3 4 5 6 7
void read () {
// read from serial (while(true))
// ...
// if something read: callback
readCallback();//Error need to provide a TMyClass object for this function to operate on.
}
#include <iostream>
usingnamespace std;
class TMyClass; //Forward declaration
class TMySerialReader
{
public:
void (TMyClass::*readCallback)();
TMySerialReader() {
readCallback = 0;
}
void read (TMyClass *pMC) //change this function to take a TMyClass pointer
{
// read from serial (while(true))
// ...
// if something read: callback
(pMC->*readCallback)();//Call the function pointer
}
};
class TMyClass
{
public:
void ProcessRead(){
cout << "Process bytes from serial\n";
}
void run()
{
TMySerialReader *caller = new TMySerialReader;
caller->readCallback = &TMyClass::ProcessRead;
caller->read(this); //Pass a pointer to the TMyClass object
}
};
int main() {
TMyClass instance1;
instance1.run();
return 1;
}
Great. Still in your version guestgulkan I must know the class TMyClass beforehand. So what I could do is create an abstract base class, which contains a virtual method void ProcessRead().