| Although function pointers are widely used to implement function callback, C ++ also provides an important method to implement callback functions, that is, function objects. Function objects (also known as operators) are common class objects that overload the () operator. Therefore, in terms of syntax, function objects are similar to common functions. Using function objects to replace function pointers has several advantages. First, because objects can be modified internally without modifying external interfaces, the design is more flexible and flexible. Function objects also have data members that store previous call results. When using a common function, you need to store the previously called results in the full or local static variables, but the full or local static variables have some defects that we do not want to see. Secondly, the compiler can implement inline calls in function objects, which further enhances the performance. This is almost impossible in function pointers. The following example illustrates how to define and use function objects. First, declare a common class and reload the "()" OPERATOR: Class negate { Public: Int operator () (int n) {return-N ;} }; In the reload operation statement, remember that the first circular arc is always empty because it represents the name of the overloaded operator. The second circular arc is the parameter list. Generally, the number of parameters is fixed when the operator is overloaded, but the number of parameters is different when the operator is overloaded. It can have any number of parameters. Because the built-in operations in negate are one dollar (only one operand), the overloaded "()" operator also has only one parameter. The return type is the same as the parameter type-int in this example. The function returns an integer opposite to the parameter symbol. Use Function objects Now we define a function called callback () to test the function object. Callback () has two parameters: int and negate reference. Callback () uses the function object neg as a common function name: # Include <iostream> Using STD: cout; Void callback (int n, negate & NEG) { Int val = neg (n); // call the overloaded operator "()" Cout <val; } In code, note that neg is an object, not a function. The compiler splits the statement Int val = neg (N ); Convert Int val = neg. Operator () (n ); Generally, function objects do not define constructor and destructor. Therefore, no problems will occur during creation and destruction. As mentioned above, the compiler can inline overload operator code, so it avoids runtime problems related to function calls. To complete the preceding example, we use the main function main () to implement callback () parameter transfer: Int main () { Callback (5, negate (); // output-5 } In this example, an integer 5 and a temporary negate object are passed to callback (), and the program outputs-5. Template function object From the above example, we can see that its data type is limited to int, while universality is one of the advantages of function objects. How to create a universal function object? The method is to use a template, that is, to define the overloaded operator "()" as a class member template, so that the function object applies to any data type, such as double, _ int64 or char: Class genericnegate { Public: Template <class T> T operator () (T) const {return-T ;} }; Int main () { Genericnegate negate; Cout <negat( 5.3333); // double Cout <negate (0000000000i64); // _ int64 } It is quite difficult to use a common callback function to implement the above flexibility. Function objects in the standard library The C ++ standard library defines several useful function objects that can be put into STL algorithms. For example, the sort () algorithm uses The predicate object is the third parameter. The object returns a boolean result. Templated function object. You can pass greater or less to sort () to forcibly sort in ascending or descending order: # Include <functional> // for greater <> and less <> # Include <algorithm> // For sort () # Include <vector> Using namespace STD; Int main () { Vector <int> VI; // .. Fill Vector Sort (VI. Begin (), VI. End (), greater <int> (); // descending) Sort (VI. Begin (), VI. End (), less <int> (); // ascending) } |