CallBack Function--1

It is very convenient to write callback functions in C. It is a bit more troublesome to define callback functions in C++. Member functions involve a this pointer problem. The static member function in C++ has no this pointer and can also be used directly as a callback function. The C++ member function address is uniquely determined, and the data variable address is variable, so the compiler uses the this pointer to connect these two parts. When we call the C++ member function, the compiler will add a this pointer to the parameter.

There is a class CTest

class CTest
{
public:
void DoMsgFunc1(char* pMsg,int nID)
{
}

void RegiestMsg(int nSrcID,DoMessageFunc pFunc)
{
m_pFunc = pFunc;
}

void HandleMessage(int nMsgID, char* pMsg, int nID)
{
(this->*m_pFunc)(pMsg,nID);
}

private:
DoMessageFunc m_pFunc;
};

Define a callback function prototype in
CTest : typedef void (CTest::*DoMessageFunc)(char* pMsg,int nID);
This can be used directly in the class.

When registering the callback function, use the following example
CTest obj;
obj.RegiestMsg(13,&CTest::DoMsgFunc1);

If CTest has many derived classes, such as
class CTest1: public CTest

When CTest1 registers the callback function, you need to force conversion, as follows
CTest1 obj1;
obj1.RegiestMsg(11,(DoMessageFunc)&CTest1::DoMsgFunc2);

The message mapping in MFC is the same. The classes that can perform message mapping are all derived from CCmdTarget. Look at the implementation of the ON_COMMAND macro definition.

#define ON_COMMAND(id, memberFxn) /
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, /
static_cast AFX_PMSG (memberFxn) },

The definition of AFX_PMSG is as follows:
typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void)

 

 

 

 

Callback functions are used more often. In fact, the so-called callback functions are function pointers, but in object-oriented programming, we often use them for very clever purposes, such as class encapsulation; or more often Realize dynamic binding; hehe isn't this the legendary polymorphism in C++.
First, let's briefly introduce the function pointer:

Copy code

#include<iostream>
typedef int(*callback)(int);
using namespace std;
class X
{
protected: int xx;
public:
X()
{
xx=11;
// hh=22;
}
static int get_hh(int a)
{
cout<<"函数get_hh"<<endl;
return a;
}
};
class Y
{
private: int xx;
  X   X_class;
  callback lp;
public:
Y()
{
xx=7;
}
int hehe(callback lp)
{
lp(xx);
return xx;
}
void xixi()
{
lp=&X::get_hh;
}
};
int f_xx(int ​​a)
{
cout<<"This is the global function f_xx:"<<a<<endl;
return a;
}
int main(int argc, char *argv[],char env[])
{
int xx;
callback lp;
xx=111;
cout<<"Haha!!"<<endl;
cout<<"Step 1: Function pointer"<<endl<< "------------------------------------------------- --------"<<endl;
lp=&X::get_hh;
cout<<"This is the static member function get_xx:"<<endl;
cout<<lp(xx) <<endl;
lp=&f_xx;
cout<<"This is the direct global function f_xx of the function pointer: "<<lp(xx)<<endl;
cout<<"Step 2: Cross-class callback"<<endl<<"-------------------------------- -------------------------"<<endl;
Y Y_class;
lp=&X::get_hh;
cout<<"This is in the Y class The method in class X is called "<<endl;
cout<<Y_class.hehe(lp)<<endl;
cin>>xx;
return 0;
}


The main thing to note is that when using function pointers, if the pointed function is in a certain class, the function must be a static member function
and the declaration format of the function pointer. It's weird. Feeling it, let's use it to do some object-oriented things that should be done:

Copy code

include<iostream>
using namespace std;
typedef int(*callback)(int);
class X
{
public:
int X_test(callback lp,int a)
{
a--;
cout<<" Before executing the callback function, pass in parameters Becomes: "<<endl;
cout<<a<<endl;
a=lp(a);
cout<<" After executing the callback function, the incoming parameter becomes: "<<endl;
cout<<a<< endl;
return a;
}
};
class Y
{
protected: int xx;
private: X X_class;
  callback lp;
public:
Y(int a)
{
xx=a;
}
static int hehe(int a)
{
for(int i=1;i<=10;i++)
{
  a++;
}
return a;
}
void xixi()
{
X c_x;
lp=&hehe;
xx=c_x.X_test(lp,xx);
cout<<"final As a result, the xx passed to class Y becomes: "<<endl;
cout<<xx<<endl;
}
};
int main(int argc,char *argv[],char env[])
{
int xx;
Y *y_c=new Y(100);
y_c->xixi();
return 0;
}



In this way, the methods in the Y class are used in the X class. Now our X class is just for addition, and the subtraction is placed in the Y class. Of course, this is only simplified for the sake of understanding, it is just an analogy, for example, a class implements data Processing and the other one implements view processing. Is it?

Guess you like

Origin blog.csdn.net/geggegeda/article/details/4337813