C + + Domain callback function Summary < one >----common use

Source: Internet
Author: User

Brief introduction:

The callback function is a C programming-based Windows SDK technology, not for C + +, the programmer can direct a C function as a callback function, but if you try to directly use the C + + member function as a callback function will have an error, and even compile cannot pass. The normal C + + member function implies a transfer function as a parameter, that is, the "This" pointer, C + + by passing a pointer to its own member function to implement program functions can access C + + data members. This also allows you to understand why multiple instances of a C + + class can share member functions but do have different data members. Because of the role of the this pointer, a callback member function is installed as a callback function because the implied this pointer does not match the number of function arguments, which causes the callback function to fail to install. In theory, the member functions of C + + classes cannot be used as callback functions. But in C + + programming we always want to implement its function within the class, that is, to maintain the encapsulation, if the callback function to write common functions have a lot of inconvenience. After searching and researching on the Internet, several ingenious methods have been found, which can make the class member function use as the callback function.

Usage scenarios:

A callback function is a function that cannot be explicitly called, and a call is implemented by passing the address of the callback function to the caller. callback function use is necessary, when we want to implement different content through a unified interface, it is very appropriate to use the back-off function. For example, we wrote different display functions for several different devices: void TVshow (); void Computershow (); void Notebookshow () ... Wait a minute. This is where we want to use a uniform display function, and we can then use the back function.
void Show (void (*PTR) ());
Different callback functions are called when used according to the parameters passed in. Different programming languages may have different syntaxes, and here is an example of a callback function in C, where one callback function takes no arguments and the other callback function has parameters. As an example:

Test.h

#include  <stdlib.h> #include  <stdio.h>int test1 () {     for   (int i=0; i<30; i++)      {           printf ("the %d th charactor is: %c/n",                         i,  (char) (' a '  + i%26));   }   return 0;} Int test2 (Int num) {  for  (int i=0; i<num; i++)    {     printf ("the %d th charactor is: %c/n",                          i,  (char) (' a '  + i%26));   }  return 0;} Void caller1 (int  (*PTR))//pointer to function as function parameter {&NBsp;     (*ptr) ();} Void caller2 (int n, int  (*ptr) (int n))//pointer to function as function parameter,                      // The first parameter here is the,{    (*ptr) (n) of the pointer service pointing to the function;} Int main ( int argc, char *argv[], char *envp[] ) {      printf ("************************/n");      caller1 (Test1);  // Equivalent to calling Test1 ();       printf ("&&&&&&*********************** */n ");      caller2 (30,&NBSP;TEST2);  //equivalent to calling Test2 ();      return 0;}

The above is achieved by passing the address of the callback function to the caller, but it is important to note the use of the parameter callback function. To implement a callback, you must first define a function pointer. The definition of a function pointer a little bit here. For example: Int (*ptr) (int n); Here ptr is a function pointer, where the parentheses (*PTR) cannot be omitted, because the parentheses have precedence over the asterisk, which is a function declaration with the return type integral type.

Reference for this paragraph:http://zq2007.blog.hexun.com/9068988_d.html


Here is an example of using the Linux C + + thread creation function Pthread_create, which has the following prototype:

int  pthread_create (&NBSP;PTHREAD_T&NBSP;*RESTRICT&NBSP;TIDP  ,  const &NBSP;PTHREAD_ATTR_T&NBSP;*RESTRICT&NBSP;ATTR&NBSP;,&NBSP; void *  (*START_RTN) ( void *)  ,  void  *restrict arg );

    1. The first parameter is a pointer to the thread identifier.

    2. The second parameter is used to set the thread properties.

    3. The third parameter is the starting address of the thread's running function, the callback function.

    4. The last parameter is the parameter that runs the function.


Here we focus only on the third parameter, Start_run, which is a function pointer to a function that takes void* as a parameter and returns a value of void*, which is used as the thread's callback function, and the code of the function executes after the thread starts.

Method One: The callback function is a normal function, but the member function is executed in the function body

Class myclass  {      pthread_t tid;  public:       void func ()       {           //Child Thread Execution code       }         bool startthread ()       {//start sub-thread            int ret = pthread_create ( &TID ,                    null , callback , this );           if ( ret != 0 )                return false;          else               return true;      }  };     static void* callback ( void* arg )   {//callback function         ((myclass*) arg)->func (); Call member function       return  null;  }    int main ()   {       myclass a;      a.startthread ();   }

The class MyClass needs to open a child thread within itself to execute the code in the member function func (), which is started by calling the Startthread () member function. Here the callback function callback is written out of the class, the passed parameter is a pointer to the MyClass object (in Pthrad_create () is specified by the 4th parameter this), the callback function through the casting of void* into myclass*, Then call Arg->func () to execute the code for the child thread. The principle of doing this is to give the pointer of the current object as a parameter to an external function, and then call the class member function by the external function, take the external function as the callback function, but execute the function of the member function, which is equivalent to a layer of transformation in the middle. The drawback is that the callback function is outside the class and affects encapsulation, where callback () is limited to static, preventing this function from being called in other files.


Method Two: The callback function is a static member function within the class, within which the member function is called

Make a slight change to the method one, and move the callback function into the class MyClass, which preserves the encapsulation. The code is as follows:

class myclass  {      static myclass* curmy;// The object that stores the callback function call       static void* callback (void*);//callback function        pthread_t tid;      void func ()        {          //Child Thread Execution code        }            void setcurmy (       {//sets the object that the current object calls for the callback function            CurMy = this;      }  public:       bool startthread ()       {//start sub-thread            setcurmy ();          int  Ret = pthread_creaTe ( &TID , NULL ,                       MyClass::callback , NULL );           if ( ret != 0 )                return false;           else               return true;      }  };   Myclass* myclass::curmy = null;  void* myclass::callback (void*)   {       curmy->func ();      return null;   }    int main ()   {      myclass  a;     &nbSp;a.startthread ();   } 

the class MyClass has 1 static data member Curmy and a static member function callback. The curmy is used to store a pointer to an object that acts as the parameter arg for the callback function in method one. Callback as a callback function, executes the code of Curmy->func (). Call Setcurmy () before each thread is established to make Curmy point to the current self. the benefit of this approach is that encapsulation is well protected, MyClass exposes only one interface Startthread (), and the child thread code and callback functions are set to private and not visible to the outside world. In addition, callback parameters are not used, and parameters can be passed in from outside. However, before starting a child thread for each object, be sure to call Setcurmy () to let Curmy correctly point to itself, otherwise the thread will be opened for other objects, which can cause serious consequences.


class myclass  {      pthread_t tid;       void func ()       {           //Child Thread Execution code       }  public:       bool startthread ()       {//start sub-thread            typedef void*  (*func) (void*);//define the FUNC type is a pointer to a function,                                  //The function parameter is void* and the return value is void*           FUNC callback =  (func) &myclass::func;//cast FUNC () Type of           int ret = pthread_create (  &tid , null , callback , this );           if (  ret != 0 )                return false;          else               return true;       }  };    int main ()   {       myclass a;      a.startthread ();   }

This method is the principle thattheMyclass::func will eventually be converted to void func (MyClass *this), meaning that the this pointer to the object itself is inserted before the first parameter. You can use this feature to write a non-static class member method directly as a thread callback function. For compilers, the two function pointers, void (MyClass::* FUNC1) () and void* (*func) (void*), look very different, but their final form is the same, Therefore, you can cast the member function pointer into a pointer to a normal function as a callback function. The pointer to the current object is passed as a parameter to the callback function (member function Func) in order to know which object the thread was set up for. The encapsulation of method three is better than method two, because there is no problem involving multiple objects sharing a static member, each object can start its own thread independently of other objects.


Note: In combination with the Tr1::function object, you can get better results, see http://blog.csdn.net/this_capslock/article/details/38564719 for details.

Reference for this paragraph: http://blog.csdn.net/this_capslock/article/details/1700100

This article is from the "GDT Commentary" blog, make sure to keep this source http://844133395.blog.51cto.com/3483632/1837890

C + + Domain callback function Summary < one >----common use

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.