In fact, all threads are used to process C functions, rather than C ++ class member functions. The standard library provides an API function. This function uses the callback function pointer as the thread's Execution Code and calls the callback function in a separate thread. The problem is that in such a thread library, the thread that executes object member functions cannot be created; only common functions can be used. Therefore, the following code fails:
# Include "class1.h"
Int func (void * PARAM)
{
Pthread_t ptid;
// The following call causes a compiler error: "cannot convert'' void (class1: *) () ''to'' void (*)()''"
// The conversion type is not allowed.
Return pthread_create (& ptid, null, & class1: some_method, null );
}
The code above fails to be compiled because the first parameter passed to pthread_create () is a member function pointer of the class class1, rather than a common function pointer. In terms of concept, common functions and class member functions are completely different. Not even if forced type conversion is performed. How can this problem be solved?
Method 1: use static member functions
The first solution is to make the callback member function static. Because static member functions do not contain the implicit parameter "this ". Therefore, you can use the address in the parameter as a pointer to a common function. If you want to access the data member of an object from a static member function, explicitly input the object address. For example:
Class hack { PRIVATE: Int X; Public: Int get_x (); Static void func (hack * pthis); // static member function Void func2 (); // non-static member function }; Void hack: func (hack * pthis) { Int y = pthis-> get_x (); // data member accessing the object } |
This method works in most cases, but sometimes the member functions cannot be declared as static, that is, the member functions are virtual functions or are using third-party classes that cannot be modified. In this case, it is difficult to solve the problem by using methods.
Method 2: process non-static member functions
Assume that the non-static member function func2 () of the hack class needs to be called in a separate thread (). You do not need to directly pass the member function address to thr_create (), declare a common function intermediary (void *) with the void * parameter, and then call it:
Void intermediary (void *); |
Create a structure, which is defined as follows:
Struct { Hack * P; // Class Object Pointer Void (Hack: * PMF) (); // member function pointer }; |
Create a structure instance and fill in the structure with the desired object address and member function address (for details about the member function pointer content, see other articles in the VC knowledge base ).
A A; // structure instance Hack h; // create an object // Fill Structure A. p = & H; A. PMF = & hack: func2; // obtain the member function address. |
Now let's go back and implement the intermediary () function:
Void intermediary (void * PTR) { A * pA = static_cast <A *> (PTR); // forcibly convert P to * Hack * pH = pa-> P; // extract the hack object address from. Void (Hack: * PMF) () = pa-> PMF; // retrieves PTR to the member function (PH-> * PMF) (); // call a member function } |
Finally, pass the intermediary () Address to thr_create ():
Pthread_create (& ptid, null, intermediary, null ); |
Pthread_create () calls the function intermediary () and passes the address of a to it. Intermediary () expands structure a from its pointer parameter and calls the expected member function. This indirect processing can safely start member functions in a separate thread, even if the thread library does not support member functions. To call different member functions of different classes, you can convert structure A to a class template and convert the function intermediary () to a function template. Thus, the compiler automatically generates code for most sample files.
Source: http://www.yesky.com/345/1658345.shtml