前言
本篇文章不讨论function和bind的语法,指在讨论在一种场景下去如何使用回调函数。
背景
我们在代码中会定义各种类,一些类用于接收信息,一些类用于处理信息,我们希望一个类就只干某一些事情,其他的事情交给专业的人(类)去处理,不要越权,这样可以使得我们的代码耦合性更低,那么这里就产生回调函数的使用情况了。
假设一个实际背景
假设现在的场景是一个婚介公司和一对新人,我们新人肯定不需要考虑我结婚的时候场景具体布置是什么样子,我需要告诉公司我想要一个怎么样的效果即可,还有一些主持的台词那些都不是我们新人该考虑的事情,我们新人只需要在那一天到场,然后跟着主持去做就行。那么我写了如下代码。
#include <iostream>
#include <functional>
#include <sys/eventfd.h>
#include <string>
#include <unistd.h>
class MatrimonialPair
{
private:
std::function<void(int, std::string&)> mycallback_;
std::string name_;
int wakefd_;
public:
MatrimonialPair(std::string& name):name_(name), wakefd_(eventfd(0, 0)) {}
void setmycallback_(std::function<void(int, std::string&)> fn) { mycallback_ = fn; }
void think()
{
uint64_t val;
read(wakefd_, &val, sizeof(val));
printf("我要开始思考我要什么时候结婚了.....\n");
printf("先输入结婚的多少号吧,再输入结婚场景吧\n");
int id;
std::string message;
std::cin >> id >> message;
printf("ok 我思考好了\n");
mycallback_(id, message);
sleep(2);
}
void wakeup() { uint64_t val = 1; write(wakefd_, &val, sizeof(val)); }
};
class MatrimonyCompany
{
private:
MatrimonialPair M;
public:
MatrimonyCompany(std::string& name):M(name)
{
M.setmycallback_(std::bind(&MatrimonyCompany::Omssage, this, std::placeholders::_1, std::placeholders::_2));
}
void Omssage(int id, std::string& message)
{
printf("公司已经接收到了新人定的时间了%d号,并且场景是%s,我们要开始布置和准备了,让我们一起祝福他们吧!!\n", id, message.c_str());
}
void think() { M.think(); }
void wakeup() { M.wakeup(); }
};
int main()
{
std::string name = "露西";
MatrimonyCompany M(name);
printf("告诉他们可以开始思考了\n");
M.wakeup();
printf("休眠五秒钟,开始告诉婚介公司具体的时间和场景\n");
sleep(5);
M.think();
return 0;
}
这里使用eventfd去模拟有事件来临,也就是上面说的接受信息类,然后我们让专门的处理类去处理这些事情,我们只需要转达我们收到的信息即可。
首先让MatrimonialPair设置一个回调函数,用于传递两个参数,时间是多少号,还有一个参数是选择的场景是什么
先调用wakeup告诉新人可以开始思考了,之后休眠时间代表思考时间,思考完成之后将思考的结果作为参数传递给婚介公司,大致就是这样一个流程,让我们来看看运行的效果。
休眠五秒钟之后
输入我们想要的时间和场景
总结
本篇文章至此,总的来说我们设计的核心理念是合适的事情交给合适的人去做,每个人只需要完成自己该完成的事情即可。我是一个厨师我的任务把菜做好就行了,你不会还等着我给你去端盘子洗盘子吧。