function的玩法有很多,很重要的一个就是用于事件回调
以前用的某些数据库有的用面向对象方法,用一个专门的事件类,经过重写虚成员函数来实现事件的触发,但是这种方法如果要添加多个事件的话比较麻烦。
现在的很多都是基于对象通过function来实现的,这样就很方便管理每个事件的添加与删除了:
下面是一个简单的例子,类似C#的关键字event来保存委托的注册事件
头文件:
#ifndef COLLECTION_H
#define COLLECTION_H
#include <iostream>
#include <functional>
#include <string>
#include <vector>
#include <algorithm>
#include <list>
//数据存储类
class Collection
{
public:
typedef std::function<void(const std::string&)> _EVENT; //可以注册的事件类型
Collection() :
m_data(std::vector<std::string>()),
m_pushEvents(std::list<_EVENT>()),
m_removeEvents(std::list<_EVENT>())
{}
Collection(const Collection&) = delete;
~Collection() {}
//push
void pushData(const std::string& data)
{
m_data.emplace_back(data);
std::for_each(m_pushEvents.begin(), m_pushEvents.end(), [&](_EVENT ev) { ev(data); });
}
//remove
bool removeData(const std::string& data)
{
int i = 0;
for (auto& _data : m_data)
{
if (_data == data)
{
//顺序无关可以这样删除
std::swap(m_data.at(i), m_data.back());
m_data.pop_back();
std::for_each(m_removeEvents.begin(), m_removeEvents.end(), [&](_EVENT ev) { ev(data); });
return true;
}
i++;
}
return false;
}
void addPushEvent(_EVENT&& ev)
{
m_pushEvents.push_back(std::forward<_EVENT>(ev));
}
void addRemoveEvent(_EVENT&& ev)
{
m_removeEvents.push_back(std::forward<_EVENT>(ev));
}
void rPushEvent(int index)
{
if (index >= m_pushEvents.size())
throw;
int i = 0;
for (auto iter = m_pushEvents.begin(); iter != m_pushEvents.end(); iter++)
{
if (i == index)
m_pushEvents.erase(iter++); //记得++
}
}
void rRemoveEvent(int index)
{
if (index >= m_removeEvents.size())
throw;
int i = 0;
for (auto iter = m_removeEvents.begin(); iter != m_removeEvents.end(); iter++)
{
if (i == index)
m_removeEvents.erase(iter++);
}
}
private:
std::vector<std::string> m_data;
std::list<_EVENT> m_pushEvents;
std::list<_EVENT> m_removeEvents;
};
#endif // !COLLECTION_H
测试文件main.h
#include <iostream>
#include "Collection.h"
//push事件1
void handler1(const std::string& str)
{
std::cout << "pushEvent1,pushed data:" << str << std::endl;
}
//push事件2
void handler2(const std::string& str)
{
std::cout << "pushEvent2,pushed data:" << str << std::endl;
}
//remove事件
void handler3(const std::string& str)
{
std::cout << "removeEvent,remove data:" << str << std::endl;
}
int main(int argc, char* argv[])
{
Collection col;
Collection::_EVENT ev = std::bind(&handler1, std::placeholders::_1);
col.addPushEvent(std::move(ev));
col.pushData("hello");
std::cout << std::endl;
ev = std::bind(&handler2, std::placeholders::_1);
col.addPushEvent(std::move(ev));
col.pushData("world");
std::cout << std::endl;
col.rPushEvent(0);
col.pushData("hello world");
std::cout << std::endl;
ev = std::bind(&handler3, std::placeholders::_1);
col.addRemoveEvent(std::move(ev));
col.removeData("hello world");
return 0;
}
欢迎批评改正