消息映射深度探索(4):职责链模式 - 使用虚函数替换映射表
来源:互联网 发布:保定seo价格 编辑:程序博客网 时间:2024/06/10 02:13
转自:http://blog.csdn.net/hjsunj/article/details/2028597
下面我们将介绍另一种实现消息映射的方式:职责链模式
#include <iostream>
#include <map>
#include <cassert>
#define PRINT( msg ) { std::cout << msg << std::endl; }
#define FUNC( func ) void func() { PRINT( #func##"()" ); }
#define MFUNC( class, func ) void func() { PRINT( #class##"::"###func##"()" ); }
#define VMFUNC( class, func ) virtual MFUNC( class, func )
enum MsgID {
MsgID_1,
MsgID_2,
};
namespace COR { // chain of responsibility
class Wnd;
typedef void (Wnd::*MemberFunc)();
class Wnd {
public:
virtual void HandleMsg( int id ) {
switch ( id ) {
case MsgID_1: Handle1(); break;
case MsgID_2: Handle2(); break;
}
}
private:
MFUNC( Wnd, Handle1 );
MFUNC( Wnd, Handle2 );
};
class MyWnd : public Wnd {
public:
virtual void HandleMsg( int id ) {
switch( id ) {
case MsgID_1: Handle1(); break;
default: Wnd::HandleMsg( id );
}
}
private:
MFUNC( MyWnd, Handle1 );
};
}
namespace AutoTest {
void TestCORMsgMap() {
using namespace COR;
Wnd* wnd = new MyWnd;
wnd->HandleMsg( MsgID_1 );
wnd->HandleMsg( MsgID_2 );
}
}
void main() {
AutoTest::TestCORMsgMap();
}
原理
不需要消息映射表,而是利用虚函数HandleMsg()向父类递归查找,详情可参考《设计模式》职责链模式。
细节
1. 可以把switch...case用查找表替换掉,但绝非必要。通常使用此法是在有封装之必要时才会采取的措施,详情可参考
http://blog.csdn.net/hjsunj/archive/2008/01/07/2028597.aspx
http://blog.csdn.net/hjsunj/archive/2008/01/11/2037354.aspx
2. 使用NVI模式(《Effective C++ 3rd》chapter35)让思路更加清晰,此时需借助查找表
将HandleMsg变为非虚函数:
void HandleMsg( int id ) {
MemberFunc func = Lookup( id );
if ( func != NULL ) {
(this->*func)();
}
}
virtual MemberFunc Lookup( int id ) {
// 如果thisclass有id之处理函数,返回之
// 否则返回BaseClass::Lookup( id );
}
优缺点
1. 实现简单:不再需要定制宏,不再需要建立消息映射表,所需的只是重写虚函数。
2. 节省内存:由于不再需要为每个派生类准备查找表,节省内存是自然而然的事。
2. 效率低下: 通常使用虚函数的效率会高于查找表(《设计模式》p204),但那只对一次调用成立。职责链模式对虚函数递归调用,其时间开销必然要高于映射表方案的迭代查找。
- 消息映射深度探索(4):职责链模式 - 使用虚函数替换映射表
- 消息映射深度探索
- 消息映射深度探索(2):MFC的做法 - 使用消息映射表
- 消息映射深度探索(3):使用宏简化操作
- 消息映射深度探索(1):基础面
- 消息映射深度探索(5):总结
- MFC为何使用消息映射表而不用虚函数?
- MFC为何使用消息映射表而不用虚函数?
- MFC为何使用消息映射表而不用虚函数?
- MFC为何使用消息映射表而不用虚函数?
- MFC为何使用消息映射表而不用虚函数?
- C++虚函数和消息映射机制
- 探索MFC笔记——消息映射
- Windows消息映射函数原型
- 消息映射表
- 消息映射表
- 消息映射表
- mfc 通过消息映射调度消息 虚函数 WindowProc
- 消息映射深度探索(1):基础面
- 消息映射深度探索(2):MFC的做法 - 使用消息映射表
- ch05 ex editor
- 消息映射深度探索(3):使用宏简化操作
- 源代码下载网站
- 消息映射深度探索(4):职责链模式 - 使用虚函数替换映射表
- 在Visual C++ 2005中使用 GNU Scientific Library
- Baidu Astar 130427
- 动、静态库编译顺序
- 消息映射深度探索(5):总结
- 9、C++程序中内存区域划分
- 俄罗斯方块
- http请求---请为我设置超时时间
- 10、C++在堆上分配内存