我是做网站的,打折网站建设教程下载,网站配色方法,wordpress分页插件下载一、C语言的回调函数
1.小试牛刀
#include iostream
using namespace std;
#include memory
#include stdlib.hint add(int a, int b) {return a b;
}void test01() {// 函数指针可以指向任何类型的函数#xff0c;只要函数的参数列表和返回值类型…一、C语言的回调函数
1.小试牛刀
#include iostream
using namespace std;
#include memory
#include stdlib.hint add(int a, int b) {return a b;
}void test01() {// 函数指针可以指向任何类型的函数只要函数的参数列表和返回值类型匹配即可int (*pFunc)(int,int) add;// 函数指针可以像普通函数一样被调用通过函数指针变量名加上括号的方式int result (*pFunc)(1,2);cout result endl; // 输出 3
}// typedef 返回类型(*新的函数名)(参数列表)
typedef int (*INT_func)(int,int);
void test02() {INT_func pFunc add;int result pFunc(2,3);cout result endl; // 输出 5
}// 回调函数,它允许一个函数作为参数传递给另一个函数
// 这种特性使得我们可以将一些特定的任务委托给其他函数来完成// 定义一个函数指针类型
typedef void(*Callback)(int);
// 定义一个函数该函数接受一个回调函数作为参数
void doSomething(Callback callback) {coutDoing something...endl;// 调用回调函数int data 1024;callback(data);
}// 定义一个回调函数
void printMyData(int data) {coutMy data is: dataendl;
}int main() {test01();test02();// 将回调函数传递给doSomething函数/*doSomething函数接受一个Callback类型的参数,这是一个指向函数的指针.doSomethings函数调用这个回调函数,并且将一个整型变量作为参数传递给它printMyData在此是一个简单的回调函数,它接受一个整型变量作为参数并且把它打印出来*/doSomething(printMyData);return 0;
}
打印结果
PS D:\Work\c ./bin/app
3
5
Doing something...
My data is: 1024
PS D:\Work\c
2.动态函数指针
在学习这个知识点的时候我遇到的坑非常感谢这位大佬给我指点迷津
动态函数指针free报错_编程语言-CSDN问答https://ask.csdn.net/questions/8061857?spm1001.2014.3001.5505
micthis大佬写的代码
#include iostream
using namespace std;
#include memory
#include stdlib.h
int add(int a, int b) {return a b;
}
/*动态函数指针是指在运行时根据需要动态分配和修改的函数指针它可以在程序运行时根据需要指向不同的函数,从而实现更加灵活和动态的函数调用在c中,可以使用动态内存分配函数(如malloc或new)来创建动态函数指针
*/
int test01() {// 创建一个指向函数的指针int(**pFunc)(int, int);// 使用malloc动态分配内存int size sizeof(int(*)(int, int));pFunc (int(**)(int, int))malloc(size);// 将函数指针指向 add函数*pFunc add;// 调用函数int result (*pFunc)(2, 3);cout result endl; // 输出 5// 释放内存free(pFunc);return 0;
}
int main() {test01();return 0;
}
打印结果
PS D:\Work\c ./bin/app
5
PS D:\Work\c
3.异步编程
#include stdio.h
#include stdlib.h
#include pthread.h
#include unistd.h// A的实现,一般会隐藏
typedef void (*CallbackPtr)(int);// 函数指针定义typedef struct dataCB{int data;CallbackPtr callback;
}dataCB;// 创建实例
dataCB dataCBInstance {0, NULL};void* callback_thread(void* arg) { // 此处用的是一个线程// 循环改变p-a的值为 0 1 2 3 4 5 6 7 8 9,每个3s改变一次dataCB* p (dataCB*)arg;while (1) {sleep(3);// 延时3s执行callback函数p-callback(p-data);// 函数指针执行函数,这个函数来自于应用层Bp-data (p-data 1) % 10;}
}void startup_app_A() {// 创建线程pthread_t tid;pthread_create(tid, NULL, callback_thread, (void*)dataCBInstance);
}// 给B的接口,接收注册函数
extern void SetCallBackFun(CallbackPtr cb) {printf(SetCallBackFun print! \n);dataCBInstance.callback cb;
}// //-----------------------应用者B-------------------------------
void recieve(int data) // 应用者增加的函数此函数会在A中被执行
{//do somethingprintf(B得到A的数据 %d\n,data);
}int main(void) {// 启动Astartup_app_A();SetCallBackFun(recieve);// 主函数while (1) {// std::cout main function std::endl;printf(main function\n);sleep(2);}return 0;
}
PS D:\Work\c ./bin/app
SetCallBackFun print!
main function
main function
B得到A的数据 0
main function
B得到A的数据 1
main function
main function
B得到A的数据 2
main function
B得到A的数据 3
main function
main function
B得到A的数据 4
main function
B得到A的数据 5
main function
main function
B得到A的数据 6
main function
B得到A的数据 7
main function
main function
B得到A的数据 8
main function
B得到A的数据 9
main function
main function
B得到A的数据 0
main function
B得到A的数据 1
main function
main function
B得到A的数据 2
main function
B得到A的数据 3
main function
main function
B得到A的数据 4
main function
B得到A的数据 5
main function
main function
B得到A的数据 6
main function
B得到A的数据 7
main function
main function
B得到A的数据 8
main function
B得到A的数据 9
main function
main function
B得到A的数据 0
main function
参考文章C/C面向对象OOP编程-回调函数详解回调函数、C/C异步回调、函数指针-CSDN博客https://blog.csdn.net/m0_47324800/article/details/135315345
二、C回调函数
1.动态函数指针
#include iostream
using namespace std;
#include memory
#include stdlib.h
int add(int a, int b) {return a b;
}
/*动态函数指针是指在运行时根据需要动态分配和修改的函数指针它可以在程序运行时根据需要指向不同的函数,从而实现更加灵活和动态的函数调用在c中,可以使用动态内存分配函数(如malloc或new)来创建动态函数指针
*/
typedef int(*handleFunc)(int,int);
int test01() {// 创建一个指向函数的指针int(**pFunc)(int, int);pFunc new handleFunc;// 将函数指针指向 add函数*pFunc add;// 调用函数int result (*pFunc)(2, 3);cout result endl; // 输出 5// 释放内存delete pFunc;pFunc nullptr;return 0;
}
int main() {test01();return 0;
} 2.简单回调
#include iostream
#include functional// 定义一个回调函数类型
typedef std::functionvoid(int) Callback;// 定义一个接受回调函数的函数
void process(int value,Callback callback) {std::cout传入处理值: valuestd::endl;callback(value); // 调用回调函数
}// 定义一个回调函数
int add(int value) {value 10;std::cout传出结果值: valuestd::endl;return value;
}int main() {int value 42;process(value,add); // 传递回调函数给process函数return 0;
}
执行结果
PS D:\Work\c ./bin/app
传入处理值: 42
传出结果值: 52
PS D:\Work\c 3.使用包装器function
参考文章C之可调用对象、bind绑定器和function包装器_完整实现bind和function代码c-CSDN博客https://blog.csdn.net/weixin_65743593/article/details/128963676 (1) 可调用对象
// 可调用对象
/*在C中可以像函数一样的调用的有普通函数类的静态成员函数、仿函数、lambda函数类的非静态成员函数、可被转换为函数的类的对象统称可调用对象或函数对象可调用对象有类型可以用指针存储它们的地址可以被引用类的成员函数除外
*/#include iostream
using namespace std;
class Object {
public:// 仿函数void operator()(int age, string name) {cout 年龄 age ,姓名 name endl;}// 类的非静态成员函数void show(int age, string name) {cout 年龄 age 姓名 name endl;}
};// 仿函数
void test01() {Object obj;obj(20, 呵呵哒);Object objRef obj; // 引用函数objRef(18, 小比尔);
}// lambda函数
void test02() {auto func [](int age, string name) {cout 年龄 age ,姓名 name endl;};func(20, heheda);auto funcRef func;// 引用lambda对象funcRef(23, 小比尔);
}// 类的非静态成员函数有地址但是只能通过类的对象才能调用它
// C对它做了特别处理类的非静态成员函数只有指针类型
// 没有引用类型不能引用
void test03() {Object obj;obj.show(30, 智慧老人);void(Object:: *pobj)(int, string) Object::show; // 定义类的成员函数的指针(obj.*pobj)(20, 呵呵哒);using PFun void(Object::*)(int, string);PFun pShow Object::show;(obj.*pShow)(78, 圣诞老人);
}int main() {test03();return 0;
}2C之可调用对象bind绑定器和function包装器
// 包装器function
// 包含头文件#include functional
// std::function返回值类型(参数类型列表) diy_name 可调用对象;#include iostream
#include functional
#include string
using namespace std;
enum OP {ADD,MUL,SUB
};int add(int a, int b) {return a b;
}using handleFunc functionint(int, int);
class Object {
public:int add(int a, int b) {return a b;}static int sub(int a, int b) {return a - b;}static int mul(int a, int b) {return a * b;}// 仿函数int operator()(int a, int b, handleFunc cb, OP op) {switch (op) {case ADD:cout ( a b ) ;break;case MUL:cout ( a * b ) ;break;case SUB:cout ( a - b ) ;break;}cout cb(a, b) endl;return cb(a, b);}
};void test01() {Object obj;functionint(int, int) func add;cout func(1, 2) endl;
}void test02() {Object obj;handleFunc addCB std::bind(Object::add, obj, std::placeholders::_1, std::placeholders::_2);cout addCB(1, 2): addCB(1, 2) endl;handleFunc subCB Object::sub;cout subCB(9, 3): subCB(9, 3) endl;subCB obj.mul;cout subCB(10, 6): subCB(10, 6) endl;handleFunc mulCB Object::mul;cout mulCB(3, 3): subCB(3, 3) endl;subCB obj.mul;cout mulCB(2, 6): subCB(2, 6) endl;functionint(int, int, handleFunc, OP) operCB obj;operCB(2, 3, add, ADD);operCB(4, 1, obj.sub, SUB);operCB(2, 9, obj.mul, MUL);
}int main() {//test01();test02();return 0;
} #include iostream
#include functional
using namespace std;
using handleFunc functionvoid();
class Object {
public:// 构造函数参数是一个包装器对象Object(const handleFunc f) :m_callback(f) {}void notify() {m_callback();// 调用通过构造函数得到的函数指针}
private:handleFunc m_callback;
};class Subject{
public:void operator()() { cout heheda endl; }
};int main() {Subject s;Object obj(s);obj.notify();return 0;
} #include iostream
#include functional
using namespace std;
class Person {
public:// 仿函数void operator()(int age, string name) {cout age: age ,name: name endl;}void show(int age, string name) {cout age: age ,name: name endl;}
};void test01() {Person person;// 仿函数functionvoid(int, string) opFunc bind(Person(), placeholders::_1, placeholders::_2);opFunc(20,heheda);// 类成员函数需要绑定该类的this指针 Person p1;functionvoid(Person, int, string) showFunc bind(Person::show,placeholders::_1, placeholders::_2, placeholders::_3);showFunc(p1, 17, Tom);// 为了统一将对象提前绑定functionvoid(int, string) showFunc2 bind(Person::show, p1, placeholders::_1, placeholders::_2);showFunc2(8, Jerry);
}int main() {test01();
} #include iostream
#include functional
#include thread
#include unistd.h
using namespace std;// A的实现,一般会隐藏
using CallbackPtr std::functionvoid(int);typedef struct dataCB{int data;CallbackPtr callback;
}dataCB;// 创建实例
dataCB dataCBInstance {0, NULL};void* callback_thread(void* arg) { // 此处用的是一个线程// 循环改变p-a的值为 0 1 2 3 4 5 6 7 8 9,每个3s改变一次dataCB* p (dataCB*)arg;while (1) {sleep(3);// 延时3s执行callback函数p-callback(p-data);// 函数指针执行函数,这个函数来自于应用层Bp-data (p-data 1) % 10;}
}void startup_app_A() {// 创建线程std::thread(callback_thread, (void*)dataCBInstance).detach(); // .detach()分离线程
}// 给B的接口,接收注册函数
extern void SetCallBackFun(CallbackPtr cb) {printf(SetCallBackFun print! \n);dataCBInstance.callback cb;
}// //-----------------------应用者B-------------------------------
void recieve(int data) // 应用者增加的函数此函数会在A中被执行
{//do somethingprintf(B得到A的数据 %d\n,data);
}int main(void) {// 启动Astartup_app_A();SetCallBackFun(recieve);// 主函数while (1) {printf(main function\n);sleep(2);}return 0;
}
3异步编程
#include iostream
#include functional
#include thread
#include unistd.h
using namespace std;// A的实现,一般会隐藏
using CallbackPtr std::functionvoid(int);typedef struct dataCB{int data;CallbackPtr callback;
}dataCB;// 创建实例
dataCB dataCBInstance {0, NULL};void* callback_thread(void* arg) { // 此处用的是一个线程// 循环改变p-a的值为 0 1 2 3 4 5 6 7 8 9,每个3s改变一次dataCB* p (dataCB*)arg;while (1) {sleep(3);// 延时3s执行callback函数p-callback(p-data);// 函数指针执行函数,这个函数来自于应用层Bp-data (p-data 1) % 10;}
}void startup_app_A() {// 创建线程std::thread(callback_thread, (void*)dataCBInstance).detach(); // .detach()分离线程
}// 给B的接口,接收注册函数
extern void SetCallBackFun(CallbackPtr cb) {printf(SetCallBackFun print! \n);dataCBInstance.callback cb;
}// //-----------------------应用者B-------------------------------
void recieve(int data) // 应用者增加的函数此函数会在A中被执行
{//do somethingprintf(B得到A的数据 %d\n,data);
}int main(void) {// 启动Astartup_app_A();SetCallBackFun(recieve);// 主函数while (1) {printf(main function\n);sleep(2);}return 0;
}
PS D:\Work\c ./bin/app
SetCallBackFun print!
main function
main function
B得到A的数据 0
main function
main function
B得到A的数据 1
main function
B得到A的数据 2
main function
main function
B得到A的数据 3
main function
B得到A的数据 4
main function
main function
B得到A的数据 5
main function
B得到A的数据 6
main function
B得到A的数据 7
main function
main function
B得到A的数据 8
main function
B得到A的数据 9
main function
PS D:\Work\c cmake --build build
[100%] Built target app
PS D:\Work\c ./bin/app
SetCallBackFun print!
main function
main function
B得到A的数据 0
main function
B得到A的数据 1
main function
main function
B得到A的数据 2
main function
B得到A的数据 3
main function
main function
B得到A的数据 4
main function
main function
B得到A的数据 5
main function
B得到A的数据 6
main function
main function
B得到A的数据 7
main function
B得到A的数据 8
main function
main function
B得到A的数据 9
main function
B得到A的数据 0
main function
main function
B得到A的数据 1
main function
B得到A的数据 2
main function
B得到A的数据 3
main function
main function
B得到A的数据 4
main function
B得到A的数据 5
main function
main function
B得到A的数据 6
main function
B得到A的数据 7
main function
main function
B得到A的数据 8
main function
B得到A的数据 9
main function
main function
B得到A的数据 0
main function
B得到A的数据 1
main function
main function
B得到A的数据 2
main function
B得到A的数据 3
main function
main function
B得到A的数据 4
main function
B得到A的数据 5
main function
main function
B得到A的数据 6
main function
B得到A的数据 7
main function
main function
B得到A的数据 8
main function
B得到A的数据 9
main function
main function
B得到A的数据 0
main function
B得到A的数据 1
main function
main function
B得到A的数据 2
main function
B得到A的数据 3
main function
main function
B得到A的数据 4
main function
B得到A的数据 5
main function
main function
B得到A的数据 6
main function
B得到A的数据 7
main function
main function
B得到A的数据 8
main function
B得到A的数据 9
main function
main function
B得到A的数据 0
main function
B得到A的数据 1
main function
main function
B得到A的数据 2
main function
B得到A的数据 3
main function
main function
B得到A的数据 4
main function
B得到A的数据 5
main function
main function
B得到A的数据 6
main function
B得到A的数据 7
main function
main function
B得到A的数据 8
main function
B得到A的数据 9
main function
main function
B得到A的数据 0
main function
B得到A的数据 1
main function
main function
B得到A的数据 2
main function
B得到A的数据 3
main function
main function
B得到A的数据 4
main function
B得到A的数据 5
main function
main function
B得到A的数据 6
main function
B得到A的数据 7
main function
main function
B得到A的数据 8
参考文章
c 用std::function包装类的非静态成员_c function 绑定非静态成员函数-CSDN博客https://blog.csdn.net/weixin_62953519/article/details/128438241
未完待续 ~