一、定义
回调函数就是一个被作为参数传递的函数。在C语言中,回调函数只能使用函数指针实现,在C++、Python、ECMAScript等更现代的编程语言中还可以使用仿函数或匿名函数。
回调函数的使用可以大大提升编程的效率,这使得它在现代编程中被非常多地使用。同时,有一些需求必须要使用回调函数来实现。
最著名的回调函数调用有C/C++标准库stdlib.h/cstdlib中的快速排序函数qsort和二分查找函数bsearch中都会要求的一个与strcmp类似的参数,用于设置数据的比较方法。
二、示例
jamin.h
#pragma once
#ifndef JAMIN_H_
#define JAMIN_H_
#include <iostream>
#include <string>
#include <vector>
#include "jamin_struct.h"
typedef uint32_t(*CallFun)(const std::vector<MDJamin>& jamin, const std::string error_code);
class Jamin
{
public:
static uint32_t GetJaminData(const ReqJamin& req_jamin, CallFun call_fun);
private:
};
#endif // !JAMIN_H_
jamin.cpp
#include"jamin.h"
#include"jamin_impl.h"
uint32_t Jamin::GetJaminData(const ReqJamin& req_jamin, CallFun call_fun)
{
JaminImpl::GetRef().GetJaminData(req_jamin, call_fun);
return 0;
}
jamin_struct.h
#pragma once
#ifndef JAMIN_STRUCT_H_
#define JAMIN_STRUCT_H_
#include <iostream>
#include <string>
#include <vector>
struct MDJamin
{
char username[10];
uint16_t time;
uint32_t price;
};
struct ReqJamin
{
char username[10];
uint32_t begin_time;
uint32_t end_time;
};
#endif // JAMIN_STRUCT_H_
jamin_impl.h
#pragma once
#ifndef JAMIN_IMPL_H_
#define JAMIN_IMPL_H_
#include<unordered_map>
#include<thread>
#include<unordered_map>
#include<thread>
#include"jamin.h"
class JaminImpl
{
public:
JaminImpl() {};
~JaminImpl()
{
Realese();
};
static JaminImpl& GetRef();
void Init();
void Realese();
uint32_t GetJaminData(const ReqJamin& req_jamin, CallFun call_fun);
void OnRun();
private:
std::thread worker_thread_;
std::unordered_map<uint32_t, CallFun> type_fun_map_;
ReqJamin req_jamin_;
MDJamin md_jamin_;
std::vector<MDJamin> vec_md_jamin_;
std::string error_code_;
};
#endif // JAMIN_IMPL_H_
jamin_impl.cpp
#include<cstring>
#include<Windows.h>
#include"jamin_impl.h"
JaminImpl& JaminImpl::GetRef()
{
static JaminImpl impl;
return impl;
}
void JaminImpl::Init()
{
strncpy_s(md_jamin_.username, "000001", sizeof(md_jamin_.username));
md_jamin_.time = 20210816;
md_jamin_.price = 8888;
vec_md_jamin_.push_back(md_jamin_);
strncpy_s(md_jamin_.username, "000002", sizeof(md_jamin_.username));
md_jamin_.time = 20210817;
md_jamin_.price = 9999;
vec_md_jamin_.push_back(md_jamin_);
error_code_ = "0";
worker_thread_ = std::thread(std::bind(&JaminImpl::OnRun, this));
}
uint32_t JaminImpl::GetJaminData(const ReqJamin& req_jamin, CallFun call_fun)
{
Init();
type_fun_map_[1] = call_fun;
return 0;
}
void JaminImpl::OnRun()
{
std::cout << "\n thread start successful" << std::endl;
while (true)
{
std::cout << "--------------------- OnRun ---------------------------" << std::endl;
type_fun_map_[1](vec_md_jamin_, error_code_);
Sleep(1000);
}
}
void JaminImpl::Realese()
{
if (worker_thread_.joinable())
{
worker_thread_.join();
}
}
callback_test
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include<thread>
#include<iostream>
#include<Windows.h>
#include "jamin.h"
uint32_t OnMdJamin(const std::vector<MDJamin>& md_jamin, const std::string error_code)
{
for (auto t : md_jamin)
{
std::cout << "username: " << t.username << std::endl;
std::cout << "time: " << t.time << std::endl;
std::cout << "price: " << t.price << std::endl;
}
return 0;
}
int main(int argc, char *args[])
{
ReqJamin req_jamin;
strcpy_s(req_jamin.username, "jamin");
req_jamin.begin_time = 20210815;
req_jamin.end_time = 20210816;
Jamin::GetJaminData(req_jamin, OnMdJamin);
system("pause");
return 0;
}
三、结果