Java implementation mode

Java callback functions may be familiar. Use Interface The callback function is defined in the interface. The function parameter can be interfance. When calling a function, the function that implements the interface is sufficient.

Simple example:

 public interface CallBack { public void execute(); } public void test(CallBack callBack){ System.out.println("callback"); callBack.execute();  } test(new CallBack() { @Override public void execute() { System.out.println("callback implement"); } });

Implementation of c++

C++is achieved through Function pointer (syntax of c) and std::function (syntax in c++11).

C++callback functions can be used in the following scenarios:

The callback function is a normal function

In general, the callback function is used in a situation where a result is generated in a function. The function does not care about the subsequent use of the result, but uses the callback function to process it.

You can define it first Function pointer of callback function , general format:

Return value (* pointer name) (parameter list)

 typedef void (*CaptureCallback)(string); void capturePic(CaptureCallback callback){ string t = "a pic"; callback(t); } void renderPic(string t){ print(t); } capturePic(renderPic);

The above is a simple example. The callback function for rendering images is used in the function for capturing images.

The callback function is a member function

In C++object-oriented, it is more common for a callback function to be a member function. This advantage is that after a function of a class A generates a result, it can call a member function of another class B. Class A does not have to have an instance of B.

Especially when there is an instance of A in B, if there is another instance of B in A, there will be a circular reference problem , which can also be solved, but this kind of coupling is easy to confuse the logic.

 typedef std::function<void (string)> CaptureCallback;   class CaptureController{ public: CaptureCallback callback; CaptureController(CaptureCallback callback):callback(callback){}; void capturePic(CaptureCallback callback){ string t = "a pic"; callback(t); } } class UI{ //Start capturing images void startCapture(){ CaptureController c(std::bind(&UI::renderPic,this,_1));  c.capturePic(); } //Render the picture as a callback function void renderPic(string t){ print(t); } } //main.cpp UI ui; ui.startCapture();

The above example is a good illustration of why callback functions are needed and how they are used.

The CaptureController header file has been referenced in the UI class. If the callback function is not used, the UI. h header file must also be referenced in CaptureController. h to access the renderPice This will cause a circular reference header file problem.

std::function

The member function of the class is different from the ordinary function as a callback function Function pointer , but Std:: function<return type (parameter type...)>function name

 typedef std::function<void (string)> CaptureCallback;
std::bind

When we pass in a function as a parameter, we need to use std::bind(oldFunName,arg_list) bind() function A new function object will be returned , arg_list Refers to the old function object oldFunName List of parameters for.

and arg_list In _1 _2 Is the parameter list of the new function object. _1 This is called a placeholder. Under the namespace of std:: placeholders.

 CaptureCallback callback = std::bind(&UI::renderPic,this,_1); callback("test");

When called callback("test") , actually calling UI Object's member function this.renderPir("test") So we need one more this Object pointer for

special, std::bind Function returned Number of arguments for the new function object Can be connected with oldFunName Number of parameters for Different.

give an example:

 void renderPic(string t,int a,char b); CaptureCallback callback = std::bind(&UI::renderPic,this,_1,2,'b'); callback("test");

Call here callback("test") , actually calling renderPic("test",2,'b') This function.

Of course, the application scenarios where the number of parameters of the callback function is different from the number of parameters of the function passed in are rare and can be ignored.


It should be noted that, std::function and std::bind Both are grammars of the c++11 standard.
It is also taken from the C++extension library boost.

The callback function can be either a normal function or a member function

In fact, the second way is to use std::function It can replace the function pointer in c language. At the same time, it should be noted that if it is passed in by ordinary functions, it is not necessary to pass in this The object pointer of the.

The callback function does not have to be used

Take the above example of camera capturing pictures ->rendering pictures.

Two methods can also be used to capture the sequence of pictures on the rendering interface:

Method 1
 void startCapture(){ string t; CaptureController c();  c.capturePic(t);// Parameter is a reference to string renderPic(t); } void renderPic(string t){ print(t); }

Through on startCapture Internal first call capturePic You can also call the renderPic function to process the result. But most application scenarios do not use threads

Method 2 can also be used for different threads.

Method 2

RenderPic can open a timer to retrieve the results generated by the capturePic function on a regular basis. However, the rhythm of renderPic is inconsistent with that of capturePic.

Therefore, whether to use the callback function needs to be selected according to the current application scenario.


Reference article:

Final modification: July 24, 2020
Do you like my article?
Don't forget to praise or appreciate, let me know that you accompany me on the way of creation.