C++表驱动

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;
    }
    

4 参考博客

(61条消息) c++表驱动_c++ 表驱动_Silen_p的博客-CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值