Use the member functions of the class as the callback function)

Source: Internet
Author: User

From: http://blog.csdn.net/xylary/article/details/1548596

Use class member functions as C callback Functions

Raise questions:
Callback functions are based on the C Programming Windows SDK technology, not for C ++. programmers can directly use a C function as a callback function, however, if you try to directly use the member function of C ++ as the callback function, an error will occur, and even compilation will fail.
Cause analysis:
A common C ++ member function implies a passing function as a parameter, that is, the "this" pointer, C ++ transfers a pointer to itself to its member functions so that program functions can access data members of C ++. This can also understand why multiple instances of the C ++ class can share member functions but have different data members. Because of the function of this pointer, when a CALLBACK-type member function is used as a CALLBACK function, the implicit this pointer causes the number of function parameters to be mismatched, resulting in a CALLBACK function installation failure.
Solution:
1. Do not use member functions. You can use the friend operator (friend) to directly use common C functions to enable member variables of member classes in C functions ), in C ++, you can describe the C function as a friend of the class. This processing mechanism is the same as using callback functions in common C programming.
2. Using static member functions, static member functions do not use the this pointer as an implicit parameter, so that they can be used as Callback functions. Static member functions have two major features: first, they can be used without class instances; second, they can only access static member variables and static member functions, you cannot access non-static member variables or non-static member functions. In C ++, the purpose of using a class member function as a callback function is to access all member variables and member functions. If this function is not implemented, it will not be of practical significance. We solve the problem by using static member functions to wrap non-static member functions. Class instances can be passed to static member functions by attaching parameters or global variables. Examples:
1. parameter transmission method
# Include <iostream. h>
Class TClassA
{
Public:

Void Display (const char * text) {cout <text <endl ;};
Static void Wrapper_To_Call_Display (void * pt2Object, char * text );
// More ....
};

// Static packaging function, which can call the member function Display (). It is used as a callback function.
Void TClassA: Wrapper_To_Call_Display (void * pt2Object, char * string)
{
// Explicit type conversion
TClassA * mySelf = (TClassA *) pt2Object;

// Call common member functions
MySelf-> Display (string );
}

// The host of the callback function. The callback function is used here.
Void DoItA (void * pt2Object, void (* pt2Function) (void * pt2Object, char * text ))
{
// Use the callback function
Pt2Function (pt2Object, "hi, I'm calling back using a argument ;-)");
}

// Execution example
Void Callback_Using_Argument ()
{
TClassA objA;
DoItA (void *) & objA, TClassA: Wrapper_To_Call_Display );
}

2. Global Variables
# Include <iostream. h>
Void * pt2Object; // global variable, which can point to any object
Class TClassB
{
Public:

Void Display (const char * text) {cout <text <endl ;};
Static void Wrapper_To_Call_Display (char * text );

};

// Static packaging function
Void TClassB: Wrapper_To_Call_Display (char * string)
{
// Ensure that the global variable value is correct.
TClassB * mySelf = (TClassB *) pt2Object;
MySelf-> Display (string );
}

// Call back the host of the function. Here, the call back function is used.
Void DoItB (void (* pt2Function) (char * text ))
{

Pt2function ("Hi, I'm calling back using a global;-)"); // make callback
}

// Execution example
Void callback_using_global ()
{
Tclassb objb;
Pt2object = (void *) & objb;
Doitb (tclassb: wrapper_to_call_display );
}

Note: The comparison between the above two methods shows that the static packaging function in the 2nd methods can maintain the same signature as the common member function. When the host interface of the callback function cannot be changed, this method is particularly useful. However, the use of global variables is not a good design.

========================================================== ====================

========================================================== ====================

=================================================== ======

========================================================== ====================

========================================================== ====================


Question proposal

We know that classes have the characteristics of encapsulation and information hiding. Only member functions of the class can access private members of the class. Other functions in the program cannot access private members. A non-member function can be a public member in the category. However, if all data members are defined as public members, this destroys the hidden features. In addition, it should be seen that in some cases, especially when calling some member functions for multiple times, the time overhead is required due to parameter transmission, type check, and security check, this affects the program running efficiency.

In order to solve the above problems, we propose a solution to use youyuan. Youyuan is a common function defined outside the class, but it needs to be described in the class body. In order to distinguish it from the member functions of the class, the keyword friend is used before the description. Youyuan is not a member function, but it can be a private member in the member class. Youyuan is used to improve the program running efficiency. However, it destroys the encapsulation and hiding of classes and enables non-member functions to be private members of the category.

Youyuan can be a function called youyuan function; youyuan can also be a class called youyuan class.

Youyuan Function

A friend function is a non-member function that can be a private member in the member class. In terms of syntax, youyuan functions are the same as normal functions, that is, they are defined and called in the same way as normal functions. The following example shows the application of the functions.

# Include
# Include

Class Point
{
Public:
Point (double xx, double yy) {x = xx; y = yy ;}
Void Getxy ();
Friend double Distance (Point & a, Point & B );
Private:
Double x, y;
};

Void Point: Getxy ()
{
Cout <"(" <x <"," <y <")" <endl; <font = "">
}

Double Distance (Point & a, Point & B)
{
Double dx = a. x-B. x;
Double dy = a. y-B. y;
Return sqrt (dx * dx + dy * dy );
}

Void main ()
{
Point p1 (3.0, 4.0), p2 (6.0, 8.0 );
P1.Getxy ();
P2.Getxy ();
Double d = Distance (p1, p2 );
Cout <"distance is" <D <Endl; <font = "">
}

Note: The Point class in this program describes a friend's meta function distance (). It adds the friend keyword before the description to identify that it is not a member function, but a friend's meta function. Its definition method is the same as that of a common function, but different from that of a member function, because it does not need to specify the class to which it belongs. However, it can reference. x, B. x,. y, B. Y is a private member of a class, which is referenced by an object. When calling a friend function, it is also the same as calling a common function. Do not call it like a member function. In this example, p1.getxy () and p2.getxy () are member function calls and are represented by objects. Distance (P1, P2) is the call of a friend function. It is called directly without object representation. Its parameter is an object. (The function of this program is to obtain the distance between two points based on known two-point coordinates .)


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.