First of all, although closures are often mentioned, I am not clear about the concept of closures. I vaguely feel that if function A defines and Returns function B, function B can still run normally outside function A and access the variables defined in function A. At the same time, the variables defined in function A cannot be accessed externally, it's called a closure-if this is wrong, it should be something I did not say!
Some people have written a blog saying that the closure is implemented through the new feature std: bind of C ++ 11. After thinking about it carefully, it can be implemented through the two features of C ++ 03: one is a local class and the other is a static local variable.
Static local variables
C ++ allows you to define static local variables within the function. These variables will not be destroyed when they exit the function, just like this.
- void func() {
- static int i = 0;
- cout << i++ << endl;
- }
If you call func multiple times, you will find that the value output to the console is increasing progressively. |
Local class
It is impossible to define a local function in a function. C ++ does not have this syntax. However, you can define a local class in a function. This class can only be used in this function. It is very interesting, just like this.
- Void func (){
- Class LocalClass {
- Private:
- // Define private members
- Public:
- Void run (){
- //......
- }
- } Obj;
- Obj. run ();
- }
If you want to return a local class object to the outside, you need to define an interface to receive the returned object and call the method. At the same time, use new in the function to generate an object and return its pointer, just like this
- class ILocal {
- public:
- virtual void run() = 0;
- };
-
- ILocal* func() {
- class LocalClass: public ILocal {
- public:
- virtual void run() {
- // ......
- }
- };
- return new LocalClass();
- }
|
The basic knowledge is ready. Let's talk about the process of implementing the closure below. Let's take a look at the annotations.
- # Include <iostream>
- Using namespace std;
-
- ////// Interface implementation ///////////////////////////// ///////////
- // Define a function object interface ...... Just like C # Delegation
- Class ITest {
- Public:
- // This operator is defined mainly for calling like a function, like this: obj ();
- Void operator ()(){
- Process ();
- }
-
- Protected:
- // Interface function
- Virtual void process () = 0;
- };
-
- // The following function returns an ITest object pointer.
- ITest * test (){
- // The static variables in the function are not destroyed if you leave the function, and can
- Static int count = 0;
-
- // Define a local class
- Class Test: public ITest {
- Public:
- // Implement the interface functions defined in ITest for operations
- Virtual void process (){
- Cout <"Count is" <count ++ <endl;
- }
- };
-
- // Return a new object ...... New is required here, you know
- Return new Test ();
- }
-
- /////// Function implementation ///////////////////////////// ///////////
- // Define the pointer type of the test function
- Typedef void (* Func) (const char *);
-
- // The following function returns a function in the closure.
- Func testFunc (){
- // Static local variable Initialization is 100
- Static int count = 100;
- // Static local constant
- Static const char * const NAME = "James ";
-
- // Functions cannot be defined directly, so you have to define static methods of local classes and return their pointers.
- Class Test {
- Public:
- // This definition can be used to input parameters. Likewise, there can be returned values.
- Static void process (const char * pName = NULL ){
- If (pName = NULL) {pName = NAME ;}
- Cout <pName <"Count is" <count -- <endl;
- }
- };
- Return Test: process;
- }
-
- //// // Program entry: main function //////////////////////////////////
- Int main (int argc, char * argv []) {
- ITest * pT = test ();
- Func pF = testFunc ();
-
- // The functions and objects returned from the function after multiple calls. Observe the results.
- For (int I = 0; I <10; I ++ ){
- (* PT )();
- PF (I % 2 = 0 )? NULL: "Fancy ");
- }
- }
Give a running result
- Count is 0
- James Count is 100
- Count is 1
- Fancy Count is 99
- Count is 2
- James Count is 98
- Count is 3
- Fancy Count is 97
- Count is 4
- James Count is 96
- Count is 5
- Fancy Count is 95
- Count is 6
- James Count is 94
- Count is 7
- Fancy Count is 93
- Count is 8
- James Count is 92
- Count is 9
- Fancy Count is 91
C ++ is a very flexible language. What we usually use is just the tip of the iceberg compared with C ++ Specification. Although I have not used it since year 45 due to my work relationship, it is still one of my favorite languages.
This article from the "Edge City inn xuehai Wuxi" blog, please be sure to keep this source http://jamesfancy.blog.51cto.com/2516291/1166900