c++多态,回调,和策略模式
来源:互联网 发布:什么是互联网软件开发 编辑:程序博客网 时间:2024/05/22 01:25
熟悉高级语言像c#的人应该都知道,c#中有事件的机制,qt有信号槽的机制,设想我们有个简单的任务,窗口上一个按钮,按钮内部是一个button类,我们用鼠标点击一下他,他会发出一个鼠标点击的通知,我们需要在这个通知里面做一些自己的事情。我大概总结了三种方法。
1 多态
这是最一般的方法,继承button,利用多态性质覆盖button中鼠标点击的虚方法,在虚方法里面写自己的代码即可。
2 回调
可是我们要是这样做,我们就无法方便的取到放在窗口类里面的公共数据了,这就是多态的一个不好的地方。像这样一个简单的任务,还是用回调的机制比较好一点。回调类似c#中的事件机制,在c++里实现,我们首先提供一个回调注册的方法,将回调对象保存起来,然后在事件发生的时候调用他就可以啦。回调对象用boos::funcktion类型来表达,回调对象可以是函数指针,函数对象,类成员函数,lamda表达式。
class baseClass{public: typedef boost::function<int(std::string&)> CBFunc; baseClass() { } void RaiseEvent(std::string& str) { if(cb) cb(str); } void registerCB(CBFunc cb) { this->cb=cb; }private: CBFunc cb;};int main(){ baseClass bc; bc.registerCB([](std::string& a){std::cout<<a<<std::endl;return 0;}); std::string info("fuck you"); bc.RaiseEvent(info);}
3 策略模式
上面两种方法可以解决大部分应用场合,但考虑到这样一种应用场合,你需要编写一个画图程序,有不同的工具,画矩形的,画圆的,变形的,拖动的等,你是在一个panel上面绘制。这时候怎么办?最原始的办法档让就是设置一个标记,记下当下选择的是什么工具,然后在panel的鼠标事件里进去区分,如果是判断是画圆的,就在鼠标点击的时候放一个圆对象,拖动的时候缩放;如果是画框的有不一样。如果你这样写,等你下次要扩充一个工具的时候,就累死了。因为你各种鼠标事件里面都要改一遍。优雅的实现方式是这样,你定义个事件接口,里面有各种鼠标事件,鼠标按下,鼠标释放,鼠标移动等,然后不同的工具进行不同的实现,每一个成为一个工具类,标准叫法是事件处理器,你将这个事件处理器在用户选择工具时传递给panel,panel在自身的事件里面调用事件处理器里面的相应的方法。因此工具类就可以获取到各种事件了。他可以在里面自定义自己的操作。选择不同的工具只需要切换不同的事件处理器给panel就行了,是不是很魔幻?下面上代码解释
class IEventhandle{public : virtual void onEvent1()=0; virtual void onEvent2()=0; virtual void onEvent3()=0;};class myEventhandle:public IEventhandle{public: void onEvent1() { std::cout<<"me fuck event 1"<<std::endl; } void onEvent2() { std::cout<<"me fuck event 2"<<std::endl; } void onEvent3() { std::cout<<"me fuck event 3"<<std::endl; }};class youEventhandle:public IEventhandle{public: void onEvent1() { std::cout<<"you fuck event 1"<<std::endl; } void onEvent2() { std::cout<<"you fuck event 2"<<std::endl; } void onEvent3() { std::cout<<"you fuck event 3"<<std::endl; }};class baseClass{public: baseClass():handle(NULL) { } void RaiseEvent1() { if(handle) handle->onEvent1(); } void RaiseEvent2() { if(handle) handle->onEvent2(); } void RaiseEvent3() { if(handle) handle->onEvent3(); } void registerHandle(IEventhandle* hd) { this->handle=hd; }private: IEventhandle* handle;};int main(){ baseClass bc; myEventhandle mh; bc.registerHandle(&mh); bc.RaiseEvent1(); bc.RaiseEvent2(); bc.RaiseEvent3(); youEventhandle yh; bc.registerHandle(&yh); bc.RaiseEvent1(); bc.RaiseEvent2(); bc.RaiseEvent3();}ok,这就是事实的全部真相,c#中能实现的,c++照样可以,c++中可以实现的c#不一定可以。
- c++多态,回调,和策略模式
- C语言和设计模式(策略模式)
- C语言和设计模式(策略模式)
- C语言和设计模式(策略模式)
- 11.C语言和设计模式(策略模式)
- 16、C语言和设计模式(策略模式)
- C语言和设计模式(策略模式)
- 策略模式(c++)
- 策略模式(C语言版)
- 【C++】Chapter2:策略模式
- Objective C--策略模式
- Objective C 策略模式
- Objective C--策略模式
- 策略模式(c++)
- object-c 策略模式
- 策略模式和简单工厂+策略模式
- 模板和策略模式
- 状态模式和策略模式
- HTTPS协议详解(二):TLS/SSL工作原理
- Java基础---包
- 低功耗蓝牙cc2541学习笔记之LED-2
- 接口与监听机制
- 【study】socket结合僵尸进程的处理
- c++多态,回调,和策略模式
- Java反射(三):java获取方法信息
- 动脉硬化:背景、检测手段和我们的工作
- C/C++堆栈指引
- 数字图像处理与OpenCV(2)--载入、显示、保存及修改图像
- JSON字符串
- ActiveMQ实战(二)--ActiveMQ的通信方式之P2P点对点通信(point-to-point)
- 树莓派3 上安装运行Android Things系统
- Retrofit2+Rxjava2+nucleus5(简化Presenter)+ButterKnife(减少findViewById使用)