C++表驱动
1 作用
1种用于代替多层if-else/ switch case的一种处理方式,根据不同的输入(msgType),进行不同的处理(函数指针)或赋值。表驱动法是一种编程模式,从表里查找信息而不使用逻辑语句(if 和case)。事实上,凡是能通过逻辑语句来选择的事物,都可以通过查表来选择。对简单的情况而言,使用逻辑语句更为容易和直白,但随着逻辑链的越来越复杂,查表法也就愈发显得更具有吸引力。
2 函数指针
- 定义
//using Func = std::function<int(int a, int b)>;
typedef int(*Func)(int a, int b);
using Func = std::function<int(int a, int b)>
是c++11的表示方式,可以用std::bind 绑定类成员函数。而typedef int(*Func)(int a, int b);
不能用std::bind绑定。
-
赋值对象
lambda表达式、全局函数、类静态函数、类的成员函数(通过std::bind绑定)
-
表驱动例子
int Add(int a, int b) { return (a + b); } class Test { public: int Add(int a, int b) { return (a + b); } static int Add1(int a, int b) { return (a + b); } }; using Func = std::function<int(int a, int b)>; //typedef int(*Func)(int a, int b); int main() { Test t; map<uint16_t, Func> mp = { {1, [](int a, int b) -> int { return 1; }}, // lambda {2, Add}, // 全局函数 {3, std::bind(&Test::Add, &t, placeholders::_1, placeholders::_2)}, // 类成员函数 (换成 typedef定义函数指针,这里会报错) {4, std::bind(Add, placeholders::_1, placeholders::_2)}, // 全局函数 {5, Test::Add1} // 类静态函数 }; for (const auto& itr : mp) { cout << itr.first << " " << itr.second(1, 2) << endl; } return 0; }
3 类成员函数指针
-
类成员函数指针定义
using FuncPtr = int (FuncObj::*)(int a); typedef int (FuncObj::* FuncPtr1)(int a);
-
实战
class FuncObj { public: void Register() { m_callBack.emplace_back(&FuncObj::Test1); m_callBack.emplace_back(&FuncObj::Test2); m_callBack.emplace_back(&FuncObj::Test3); //m_callBack.emplace_back(std::bind(&FuncObj::Test2, this, placeholders::_1)); // 编译过,运行错误 //m_callBack.emplace_back([&](int a) -> int {return Test3(a); }); // 编译过,运行错误 //m_callBack1.emplace_back(&FuncObj::Test1); // 编译过,运行错误 m_callBack1.emplace_back(std::bind(&FuncObj::Test2, this, placeholders::_1)); m_callBack1.emplace_back([&](int a) -> int {return Test3(a);}); } void Run() { for (const auto& itr : m_callBack) { (this->*itr)(1); } for (auto i = 0; i < m_callBack1.size(); i++) { m_callBack1[i](i); } } private: int Test1(int a) { cout << "Test1 ..." << a << endl; return a; } int Test2(int a) { cout << "Test2 ..." << a << endl; return a; } int Test3(int a) { cout << "Test2 ..." << a << endl; return a; } private: using FuncPtr = int (FuncObj::*)(int a); typedef int (FuncObj::* FuncPtr1)(int a); // 与上类似 vector<FuncPtr> m_callBack; vector<std::function<int(int a)>> m_callBack1; }; int main() { FuncObj obj; obj.Register(); obj.Run(); return 0; }