Cocos2dx <basic> callback function and related syntax

<function pointer>

Pointer: is a variable that stores a memory address. When a program is running, all objects related to running need to be loaded into memory. Functions are stored in the memory code area, functions also have addresses, and pointers can be used to store functions.

The address that points to the entry point of a function is called a function pointer.

int GetSum(int x, int y)
{
	return x+y;
}

intmain()
{
//function pointer stores the function address
int (* p) (int x, int y);
p = GetSum;
cout << p(2,3) << endl;
 return 0;
}

<callback function>

The user defines the function and implements the content of the function, and then passes this function as a parameter to the function that will be called when the function of others (system) runs.

(other people's functions will call your implemented functions during runtime),

void Display()
{
	cout << "callback function" << endl;
}

void Fun(void (*p)())
{
	p();
	cout << "The function that implements the callback function" << endl;
}

int Dop (int x)
{
	return x;
}

void fup(int (*p)(int x))
{
	cout << p(2) << endl;
}

intmain()
{
	// no parameters
	Fun(Display);
	//with parameters
	fup (Dop);
}

<bind>

bind is a template for function binding. When binding a function, you can specify some or all parameters, or no parameters, and you can adjust the relationship between the parameters.

For unspecified parameters, placeholders _1, _2 can be used. _1 represents the first parameter of the bound function, and _2 represents the second parameter of the bound function.

void Diplay()
{
	cout << "bind function binding" << endl;
}

void Dun(int x,int y)
{
	cout << x << endl;
	cout << y << endl;
}

void Du(int& x, int& y)
{
	x++;
	y++;
}

intmain()
{
	// no parameters
	auto func = bind(Diplay);
	func();
	//With parameters, the bound function does not pre-specify the first parameter
	auto fnp = bind(Thin,placeholders::_1,2);
	fnp(1);
	//With parameters, the bound function does not pre-specify the first and second parameters
	auto fgp = bind(Dun,placeholders::_1,placeholders::_2);
	fgp(3,4);
	// Parameters that are not pre-specified are passed by reference, and parameters that are pre-specified are passed by value
	int m = 5, n = 8;
	auto frh = bind (Du, m, placeholders :: _ 1);
	frh (n);
	cout << "m=" << m << endl;
	cout << "n=" << n << endl;
}

<function>----->Header file: #include<functional>

The class template function is a function encapsulation, and the instance of the function can store, copy, and call any calling target. Targets: functions, lambda expressions, etc.

void Dun(int x)
{
	cout <<"parameter not pre-specified placeholders::_1=" <<x << endl;
}

intmain()
{
	//With parameters, the bound function does not pre-specify the first parameter
	bind(Dun, placeholders::_1, 2);
	function<void(int)> func = bind(Dun, placeholders::_1);
	func(1);
}

<**Lambda expression>

a. Lambda expressions are used to define and create anonymous function objects to simplify programming.

    Lambda expression syntax: [capture list] (parameter list) mutable/ exception -> return value type {statement} 

b. Lambda expression analysis:

   (1) Capture list: It always appears at the beginning of a lambda expression. In fact, [] is a lambda expression detractor, and the compiler judges whether the following code is a lambda expression according to the detractor.

       The capture list can capture variables that are visible in the scope of the lambda until the lambda is defined (including this of the class where the lambda is located).

   (2) Parameter list: the same as the normal parameter list. Pass by value and pass by reference, this part can be omitted when there are no parameters.

   (3) mutable or exception statement: this part can be omitted. When passing the capture list parameter by value, after adding the mutable modifier, the copy passed in by value can be modified (note that it can be modified

       copy, not the value itself). The exception declaration is used to specify the exception thrown by the function, such as throwing an exception of integer type, you can use throw(int).

   (4)->Return type: Indicates the type returned by the function. If the return value is not required, you can omit -> return type directly; if the return type is clear, you can also omit this part and let the compiler

       Deduce the return type.

   (5) Function body, the content is the same as that of ordinary functions. You can use parameters from a parameter list, or you can use parameters from a capture list.

c. Capture item analysis of the capture list:

    [] --> indicates that there is no capture item

    [= ]-> indicates that the function body can use the local variables of the Lambda effective scope class, including the this of the class where it is located; pass by value

    [&]-> indicates that the function body can use the local variables of the Lambda effective scope class, including the this of the class where it is located; pass by reference

    [this]-> indicates that the function body can use the member variables of the class where the Lambda is located

    [a]-> means that a is passed by value. If you want to modify the copy of a, you should add mutable

    [&a]-> means that a is passed by reference

    [ a, &b ]-> means that a is passed by value, and b is passed by reference

    [=, &a, &b]-> means that a and b are passed by reference, other parameters are passed by value

    [&, a, b]-> means that a, b are passed by value, and the rest of the parameters are passed by reference

class Test
{
	int x = 10;
public:
	void Lambda1()
	{
		int y = 5;
		auto fun2 = [=]() { cout << y << endl; };
		fun2();
	}
	void Lambda2()
	{
		int z = 6;
		auto fun2 = [&]() { cout << z << endl;};
		fun2();
	}
	void Lambda3()
	{
		auto fun2 = [this]() { cout << this->x << endl; };
		fun2();
	}
	void Lambda4()
	{
		int a = 8;
		auto fun2 = [a]() { cout << a << endl; };
		fun2();
		auto fun3 = [a]() mutable {a++; cout << a << endl; };
		cout << a << endl;
	}
	void Lambda5()
	{
		int b = 10;
		auto fun2 = [&b]() { ++b; cout << b << endl; };
		fun2();
		cout << b << endl;
	}
	void Lambda6()
	{
		int b = 10;
		int a = 8;
		auto fun2 = [&b, a]() { ++b; cout << b << endl; cout << a << endl; };
		fun2();
	}
	void Lambda7()
	{
		int b = 10;
		int a = 8;
		auto fun2 = [&b, a](int x) {cout << a + b + x << endl; };
		fun2(5);
	}
};

intmain()
{
	Test* test = new Test();
	//[]
	auto fun1 = [] {cout << "No catch" << endl; };
	//[=]
	test->Lambda1();
	//[&]
	test->Lambda2();
	//[this]
	test->Lambda3();
	//[a]
	test->Lambda4();
	//[&a]
	test->Lambda5();
	//[a,&b]
	test->Lambda6();
	// parameter list is not empty
	test->Lambda7();
}


<Analyze the menu callback function in Cocos2dx>

a. View the create() function of the menu item

    (1) static MenuItemImage* create(const std::string&normalImage, const std::string&selectedImage, const ccMenuCallback& callback);

    (2) typedef std::function<void(Ref*)> ccMenuCallback;

    (3)  ccMenuCallback-------> function encapsulation, the encapsulated function prototype is void function name (Ref*)

b. View the functions provided by Cocos2dx: CC_CALLBACK_1

    Looking at the definition of CC_CALLBACK_1, you will find:

#define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
#define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
#define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
#define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)

   Analysis What does 0, 1, 2, and 3 represent? It represents the number of parameters that are not pre-specified in the bound function.

   We found the function prototype of CC_CALLBACK_X----->std::bind() : function binding

c. Know the ccMenuCallback in the create() function of the menu item-------> function: function encapsulation

    Know the function prototype of CC_CALLBACK_1----->bind: function binding

    The form here is different, why can it be used? The reason is that it can be encapsulated in the function function

    Simply write:

    void Func(Ref*) { }

    funtion<void (Ref*)> = bind(Func, placeholders::_1) ;


<Cocos2dx action callback function>-----> Use the callback function as a parameter

a. Create a callback action, using a parameterless callback function as a parameter

     static CallFunc * create(const std::function<void()>& func);

b. Create a callback action, using a callback function with Node* as a parameter as a parameter

     static CallFuncN * create(const std::function<void(Node*)>& func);


------------------------------------边学边补充-------------------------------------------------

(1).  菜单回调函数 , 动作回调函数: 使用回调函数作为参数。

(2).  接收回调函数作为参数的两种类型: function, bind

(3).  Lmabda表达式可以创建回调函数










Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325607414&siteId=291194637