Implement the callback of the class member function with a set of macro

xiaoxiao2021-03-06  76

Implement the callback of the class member function, existing methods, such as the CCMDTARGET class of the MFC uses a set of enumerations to distinguish parameters and return values, and then store objects and pointers with a set of arrays; and use templates to implement callbacks. This article discusses a method of implementing a callback of the class member function by macro.

Implementation requires two prerequisites: 1. The class belonging to the callback function needs to inherit from known class, preferably with the same base class. For example, COBJECT. 2. The callback function must be a class member function of public, cannot be a private, protected or static member function.

The implementation is discussed below. First add a few macros for this mechanism:

/ ********* Macros Defined for Member Function Callback *********** / # include "stdarg.h" #define nullnotifyfunc {0, 0}

#define DEFINENOTIFYFUNC (TypeName, BaseClass, RetType, Params) / typedef RetType (BaseClass :: * _ CallBackFunc ## TypeName) Params; / typedef struct _tagNOTIFYFUNC ## TypeName / {/ class BaseClass * pObject; / _CallBackFunc ## TypeName pFunc; / Void settonull () / {/ POBJECT = NULL; / PFUNC = NULL; /} / void __cdecl Assign (Class Baseclass * Pob, ...) / {/ VA_LIST MARKER; / VA_START (MARKER, POB); / POBJECT = POB ; / Pfunc = VA_ARG (Marker, _CallbackFunc ## Typename); / va_end (marker); / return; /} / int assigned (void) / {/ return pObject! = Null && pfunc! = Null; /} /} Typename , * P ## Typename, * LP ## Typename;

#define callnotifyfunc (p, params) ((p.PObject) -> * (p.pfunc)) params / ********* * * ******** * * ******** **** /

This code defines three macros: DEFINENOTIFYFUNC is used to define a callback structure class. The same base class, the same return value and the callback function of the parameter can use the same callback structure class. The syntax is as follows: DefineNotifyFunc (Structure class name, base class name, return value type, (parameter list)) where the parameter list must be enclosed in a parental bracket, even if there is only one parameter. NullNotifyFunc macro is used to initialize a callback structure empty. CallNotifyFunc is used to call a callback structure. A callback structure has the following method: settonull () is set to empty ASSIGN (Object Pointer, Function Address) assigns a value for this callback structure. Note: This function is declared that the variable parameter is to skip the C to the function type check, but the number of parameters must be in strict accordance with the definition of DefineNotifyFunc. If the wrong compiler does not give a warning, this is one of the defects of this method. Assigned () is used to test whether this structure has been assigned. Note: It can only check if the object pointer and function pointer in the structure are empty, and it is impossible to determine whether the object is valid, so it is necessary to manually empty this structure when the object with the callback function is released, otherwise it may cause a violation. This is the two deficiencies of this method.

Application example: Class ClassBase;

/ / Define a parameter is two intellectuals, returning an integer callback DefineNotifyFunc (NotifyFuncxy, ClassBase, INT, (INT, INT)); // Defines a parameter as a string, the callback structure without return value DefineNotifyFunc (NotifyProcstr , ClassBase, Void, (Char *));

Class classbase {};

Class Classa: Public ClassBase {public: // This structure uses member variables of class A. Classa () {Eventa.Settonull ();} void testproc (char * str) {Printf ("% s", STR); } Int Callb () {IF (Eventa.assigned ()) Return CallNotifyFunc (Eventa, (4, 5)); else return -1;}}

Class Classb: Public ClassBase {public: // This structure uses member variables of class B NOTIFYPROCSTR Eventb; classb () {eventb.settonull ();} int TestFunc (int x, int y) {returnix x * y;} Void Calla () {If (Eventb.assigned ()) CallNotifyFunc (Eventb, "Hello, SupeRhow / N");}};

INT Main (int Argc, char * argv []) {classa obja; classb objb; // is assigned value of the callback structure of object A, reference object B's class member function obja.eventa.assign (& objb, objb.testfunc); / / To assign a value of the callback structure of the object B, reference object A class member function objb.eventb.assign (& obja, obja.testproc); ("4 * 5 =% D / N) ", Obja.callb ()); Printf (" Some Output: / N "); // The member function of the callback A in B is objb.cAlla (); getCh (); returnography;}

转载请注明原文地址:https://www.9cbs.com/read-121661.html

New Post(0)