1、概述。
我们在C/C++编程中经常涉及到回调函数。
回调函数到底是什么呢?回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。例如,我们在win32开发里面,使用windows API时遇到的WinProc()函数,就是我们编写而由操作系统调用的函数。
2、实例
2.1 关键知识点。
一般格式: 返回值 (*指针名) (参数列表)。
作用域: 全局。
2.2 自己的回调。
在此例中,我们定义一个Person结构保存基本信息,然后创建回调,通过比较数据对象做出展示效果。
2.2.1 定义数据结构:
struct Person
{
string name;
string sex;
int age;
int id;
};
2.2.2 定义函数指针:
typedef bool(*pCallBack)(Person, Person);
2.2.3 定义主调函数:
void BubbleSort(vector<Person> arr, pCallBack func)
{
const int nSize = arr.size();
Person pers{};
for (int i = 0; i < nSize; i++)
{
for (int j = 0; j < nSize - i - 1; j++)
{
if ((*func)(arr[j], arr[j + 1]))
{
pers = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = pers;
}
}
}
for (auto it:arr)
{
cout << it.name << "\t" << it.age << "\t" << it.id << endl;
}
}
2.2.4 定义比较增长因子及设置接口:
bool g_bIncrease = true;
void SetIncrease(bool bIncrease = true);
void SetIncrease(bool bIncrease)
{
g_bIncrease = bIncrease;
if (bIncrease)
{
cout << "从小到大:" << endl;
}
else
{
cout << "从大到小:" << endl;
}
}
2.2.5 定义两种比较方法:
//比较年龄
bool CompareAge(Person per1, Person per2)
{
if (g_bIncrease)
{
if (per1.age > per2.age)
{
return true;
}
return false;
}
else
{
if (per1.age < per2.age)
{
return true;
}
return false;
}
}
//比较ID
bool CompareId(Person per1, Person per2)
{
if (g_bIncrease)
{
if (per1.id > per2.id)
{
return true;
}
return false;
}
else
{
if (per1.id <= per2.id)
{
return true;
}
return false;
}
}
2.2.6 主程序调用:
int main()
{
vector<Person> arr;
Person per;
per.name = "Gon";
per.sex = "boy";
per.age = 12;
per.id = 456325452;
arr.push_back(per);
per.name = "Killua";
per.sex = "girl";
per.age = 33;
per.id = 123254128;
arr.push_back(per);
per.name = "Kula";
per.sex = "boy";
per.age = 8;
per.id = 965754125;
arr.push_back(per);
per.name = "Leiouli";
per.sex = "girl";
per.age = 41;
per.id = 789652484;
arr.push_back(per);
cout << "初始数据:" << endl;
Show(arr);
cout << "\n\n";
cout << "age";
SetIncrease(false);
BubbleSort(arr, (pCallBack)CompareAge);
cout << "\n\n";
cout << "id";
SetIncrease(true);
BubbleSort(arr, (pCallBack)CompareId);
cin.get();
return 0;
}
2.2.7 运行效果:
2.3 系统的回调。
在这个实例中,需要学习系统快排函数qsort(),来加深回调的理解。
2.3.1 首先,添加头文件 #include “stdlib.h”
2.3.2 然后,F12看看函数声明:
_CRTIMP void __cdecl qsort(
_Inout_updates_bytes_(_NumOfElements * _SizeOfElements) void * _Base,
_In_ size_t _NumOfElements,
_In_ size_t _SizeOfElements,
_In_ int (__cdecl * _PtFuncCompare)(const void *, const void *)
);
参数一: 传进来需要排序的地址
参数二: 参与排序的数量。
参数三: 参与排序的每一个元素的空间大小。
参数四: 函数指针,确立升序还是降序。
2.3.3 接着,定义新的函数指针:
int CompareAgeII(const void* per1, const void* per2)
{
Person* pers1 = (Person*)per1;
Person* pers2 = (Person*)per2;
if (g_bIncrease)
{
if (pers1->age > pers2->age)
{
return 1;
}
return -1;
}
else
{
if (pers1->age <= pers2->age)
{
return 1;
}
return -1;
}
}
2.3.4 现在,主程序调用:
int main()
{
vector<Person> arr;
Person per;
per.name = "Gon";
per.sex = "boy";
per.age = 12;
per.id = 456325452;
arr.push_back(per);
per.name = "Killua";
per.sex = "girl";
per.age = 33;
per.id = 123254128;
arr.push_back(per);
per.name = "Kula";
per.sex = "boy";
per.age = 8;
per.id = 965754125;
arr.push_back(per);
per.name = "Leiouli";
per.sex = "girl";
per.age = 41;
per.id = 789652484;
arr.push_back(per);
cout << "初始数据:" << endl;
Show(arr);
cout << "\n" << "系统快排,age";
SetIncrease(false);
qsort(arr.data(), arr.size(), sizeof(Person), CompareAgeII);
Show(arr);
cin.get();
return 0;
}
2.3.5 最后,运行:
3、总结.
①、定义函数指针,形如:typedef bool(*pCallBack)(Person, Person);
②、定义当做形参的普通函数,形如:bool CompareAge(Person per1, Person per2);
③、定义主调函数,形如:void BubbleSort(vector<Person> arr, pCallBack func);
④、调用回调函数,形如:BubbleSort(arr, (pCallBack)CompareAge);
参考文章:https://www.cnblogs.com/tinaluo/p/8327880.html
入门萌新,浅知拙见,若有斧正,不胜感激。^ - ^