希望想理解C++委托的同学,能够从代码中悟出其中的原理。有什么不太清楚的地方,欢迎留言交流。

 #include <bits/stdc++.h>
using namespace std; #define debug(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl class AF
{
public:
AF() {}
void Func(int x){
cout << "AF::Func " << x << endl;
}
}; void (AF::*pFunc)(int) = &AF::Func; int main(int argc, char *argv[])
{
AF af;
(af.*pFunc)();
AF *paf = &af;
(paf->*pFunc)(); return ;
}

成员函数指针的操作

 #include <bits/stdc++.h>
using namespace std; #define debug(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl class AF
{
public:
AF() {}
void Func(int x){
cout << "AF::Func " << x << endl;
}
}; void (AF::*pFunc)(int) = &AF::Func; class BF
{
public:
BF() {}
void method(int x){
cout << "BF::method " << x << endl;
}
}; /* gcc-4.4.7 不支持特化与偏特化模板
template <typename N>
class Test<char, N>
{
public:
Test( char i, N j ):a( i ), b( j )
{
cout<<"模版类偏特化"<< a<< ' ' << b << endl;
}
private:
char a;
N b;
};
*/ /*
template<typename T>
class DelegateNoneMemFunc
{
void (*m_pFunc)(int);
public:
DelegateNoneMemFunc(void (*pFunc)(int) ):m_pFunc(pFunc) {}
void invoke(int value){
(*m_pFunc)(value);
}
};
*/ void NonmemberFunc(int value){
printf("NonmemberFunc: %d\n", value);
} class IDelegateHandler
{
public:
virtual ~IDelegateHandler() {}
virtual void invoke(int) = ;
}; /*
template <typename T>
class DelegateHandlerChild : public IDelegateHandler
{
public:
DelegateHandlerChild() {}
void invoke(int value){
printf("DelegateHandlerChild invoke: %d", value);
}
};
*/ //*
template <typename T>
class DelegateHandler
{
T *m_pT;
void (T::*m_pFunc)(int);
public:
DelegateHandler(T *pT, void (T::*pFunc)(int)):m_pT(pT), m_pFunc(pFunc) {} void invoke(int value){
(m_pT->*m_pFunc)(value);
}
}; template <typename T>
class DelegateNmemHandler
{
void (*m_pFunc)(int);
public:
DelegateNmemHandler(void (*pFunc)(int)):m_pFunc(pFunc) {} void invoke(int value){
(*m_pFunc)(value);
}
}; int main(int argc, char *argv[])
{
AF af;
BF bf; (af.*pFunc)();
AF *paf = &af;
(paf->*pFunc)(); // template
DelegateHandler<AF> afT(&af, &AF::Func);
afT.invoke(); DelegateHandler<BF> bfT(&bf, &BF::method);
bfT.invoke(); // 非成员函数
DelegateNmemHandler<void> nMemFunc(NonmemberFunc);
nMemFunc.invoke(); return ;
} class LuggageCompartment {
private:
int m_iLuggage; //私有变量,保存现在的行李总数
public:LuggageCompartment() {
m_iLuggage = ;
} //构造函数
int TakeoutLuggage() //取出一件行李
{
if (m_iLuggage != )
m_iLuggage--;
return m_iLuggage;
}
int InsertLuggage() //放入一件行李
{
return (++m_iLuggage);
}
int checkLuggage() //检查行李总数
{
return m_iLuggage;
}
}; class FlightSegment {
private:LuggageCompartment * m_pLC; //成员指针
public:void SetLuggageCompartment(LuggageCompartment * pLC) {
m_pLC = pLC;
} //设置成员指针
FlightSegment() //构造函数将成员指针初始化为null
{
m_pLC = NULL;
}
int checkLuggage() {
if (m_pLC == NULL)
return -;
return m_pLC->checkLuggage(); //将函数调用委托给成员指针
}
};

使用类模板

 #include <bits/stdc++.h>
using namespace std; #define debug(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl class AF
{
public:
AF() {}
void Func(int x){
cout << "AF::Func " << x << endl;
}
}; void (AF::*pFunc)(int) = &AF::Func; class BF
{
public:
BF() {}
void method(int x){
cout << "BF::method " << x << endl;
}
}; /* gcc-4.4.7 不支持特化与偏特化模板
template <typename N>
class Test<char, N>
{
public:
Test( char i, N j ):a( i ), b( j )
{
cout<<"模版类偏特化"<< a<< ' ' << b << endl;
}
private:
char a;
N b;
};
*/ void NonmemberFunc(int value){
printf("NonmemberFunc: %d\n", value);
} template <typename T>
class DelegateHandler
{
T *m_pT;
void (T::*m_pFunc)(int);
public:
DelegateHandler(T *pT, void (T::*pFunc)(int)):m_pT(pT), m_pFunc(pFunc) {} void invoke(int value){
(m_pT->*m_pFunc)(value);
}
}; // 非成员函数
template <typename T>
class DelegateNmemHandler
{
void (*m_pFunc)(int);
public:
DelegateNmemHandler(void (*pFunc)(int)):m_pFunc(pFunc) {} void invoke(int value){
(*m_pFunc)(value);
}
}; class IDelegateHandler
{
public:
virtual ~IDelegateHandler() {}
virtual void invoke(int) = ;
}; template <typename T>
class DelegateHandlerChild : public IDelegateHandler
{
T *m_pT;
void (T::*m_pFunc)(int);
public:
DelegateHandlerChild(T *pT, void (T::*pFunc)(int)):m_pT(pT), m_pFunc(pFunc) {} void invoke(int value){
(m_pT->*m_pFunc)(value);
}
}; template <typename T>
class DelegateNmemHandlerChild : public IDelegateHandler
{
void (*m_pFunc)(int);
public:
DelegateNmemHandlerChild(void (*pFunc)(int)):m_pFunc(pFunc) {} void invoke(int value){
(*m_pFunc)(value);
}
}; int main(int argc, char *argv[])
{
AF af;
BF bf;
/*
(af.*pFunc)(10);
AF *paf = &af;
(paf->*pFunc)(11); // template
DelegateHandler<AF> afT(&af, &AF::Func);
afT.invoke(3); DelegateHandler<BF> bfT(&bf, &BF::method);
bfT.invoke(4); DelegateNmemHandler<void> nMemFunc(NonmemberFunc);
nMemFunc.invoke(5);
*/
DelegateHandlerChild<AF> ac(&af, &AF::Func);
DelegateHandlerChild<BF> bc(&bf, &BF::method);
DelegateNmemHandlerChild<void> vc(NonmemberFunc); vector<IDelegateHandler *> handler;
handler.push_back(&ac);
handler.push_back(&bc);
handler.push_back(&vc); for(auto iter = handler.begin(); iter != handler.end(); iter++)
(*iter)->invoke();
return ;
}

使用多态

 #include <bits/stdc++.h>
using namespace std; #define debug(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl class AF
{
public:
AF() {}
void Func(int x){
cout << "AF::Func " << x << endl;
}
}; void (AF::*pFunc)(int) = &AF::Func; class BF
{
public:
BF() {}
void method(int x){
cout << "BF::method " << x << endl;
}
}; /* gcc-4.4.7 不支持特化与偏特化模板
template <typename N>
class Test<char, N>
{
public:
Test( char i, N j ):a( i ), b( j )
{
cout<<"模版类偏特化"<< a<< ' ' << b << endl;
}
private:
char a;
N b;
};
*/ void NonmemberFunc(int value){
printf("NonmemberFunc: %d\n", value);
} /*
template <typename T>
class DelegateHandler
{
T *m_pT;
void (T::*m_pFunc)(int);
public:
DelegateHandler(T *pT, void (T::*pFunc)(int)):m_pT(pT), m_pFunc(pFunc) {} void invoke(int value){
(m_pT->*m_pFunc)(value);
}
}; // 非成员函数
template <typename T>
class DelegateNmemHandler
{
void (*m_pFunc)(int);
public:
DelegateNmemHandler(void (*pFunc)(int)):m_pFunc(pFunc) {} void invoke(int value){
(*m_pFunc)(value);
}
}; // 多态
class IDelegateHandler
{
public:
virtual ~IDelegateHandler() {}
virtual void invoke(int) = 0;
}; template <typename T>
class DelegateHandlerChild : public IDelegateHandler
{
T *m_pT;
void (T::*m_pFunc)(int);
public:
DelegateHandlerChild(T *pT, void (T::*pFunc)(int)):m_pT(pT), m_pFunc(pFunc) {} void invoke(int value){
(m_pT->*m_pFunc)(value);
}
}; template <typename T>
class DelegateNmemHandlerChild : public IDelegateHandler
{
void (*m_pFunc)(int);
public:
DelegateNmemHandlerChild(void (*pFunc)(int)):m_pFunc(pFunc) {} void invoke(int value){
(*m_pFunc)(value);
}
}; */
// 使用宏
#define DECLARE_PARAMS(...) __VA_ARGS__
#define DECLARE_ARGS(...) __VA_ARGS__ //0个参数的委托
#define DELEGATE0(retType, name) \
DECLARE_DELEGATE(retType, name, DECLARE_PARAMS(void), ) //1个参数的委托
#define DELEGATE1(retType, name, p1) \
DECLARE_DELEGATE( \
retType, \
name, \
DECLARE_PARAMS(p1 a), \
DECLARE_ARGS(a)) //2个参数的委托
#define DELEGATE2(retType, name, p1, p2) \
DECLARE_DELEGATE( \
retType, \
name, \
DECLARE_PARAMS(p1 a, p2 b), \
DECLARE_ARGS(a, b)) //3个参数的委托
#define DELEGATE3(retType, name, p1, p2, p3) \
DECLARE_DELEGATE( \
retType, \
name, \
DECLARE_PARAMS(p1 a, p2 b, p3 c), \
DECLARE_ARGS(a, b, c)) //4个参数的委托
#define DELEGATE4(retType, name, p1, p2, p3, p4) \
DECLARE_DELEGATE( \
retType, \
name, \
DECLARE_PARAMS(p1 a, p2 b, p3 c, p4 d), \
DECLARE_ARGS(a, b, c, d)) //5个参数的委托
#define DELEGATE5(retType, name, p1, p2, p3, p4, p5) \
DECLARE_DELEGATE( \
retType, \
name, \
DECLARE_PARAMS(p1 a, p2 b, p3 c, p4 d, p5 e), \
DECLARE_ARGS(a, b, c, d, e)) //6个参数的委托
#define DELEGATE6(retType, name, p1, p2, p3, p4, p5, p6) \
DECLARE_DELEGATE( \
retType, \
name, \
DECLARE_PARAMS(p1 a, p2 b, p3 c, p4 d, p5 e, p6 f), \
DECLARE_ARGS(a, b, c, d, e, f)) //7个参数的委托
#define DELEGATE7(retType, name, p1, p2, p3, p4, p5, p6, p7) \
DECLARE_DELEGATE( \
retType, \
name, \
DECLARE_PARAMS(p1 a, p2 b, p3 c, p4 d, p5 e, p6 f, p7 g), \
DECLARE_ARGS(a, b, c, d, e, f, g)) //8个参数的委托
#define DELEGATE8(retType, name, p1, p2, p3, p4, p5, p6, p7, p8) \
DECLARE_DELEGATE( \
retType, \
name, \
DECLARE_PARAMS(p1 a, p2 b, p3 c, p4 d, p5 e, p6 f, p7 g, p8 h), \
DECLARE_ARGS(a, b, c, d, e, f, g, h)) #define DECLARE_DELEGATE(retType, name, params, args) \
class I##name { \
public: \
virtual ~I##name() { } \
virtual retType Invoke(params) = ; \
}; \
template<typename T> \
class name : public I##name { \
public: \
name(T* pType, retType (T::*pFunc)(params)) \
: m_pType(pType), m_pFunc(pFunc) { } \
retType Invoke(params) { \
return (m_pType->*m_pFunc)(args); \
} \
private: \
T* m_pType; retType (T::*m_pFunc)(params); \
}; \
template<> \
class name<void> : public I##name { \
public: \
name(retType (*pFunc)(params)) \
: m_pFunc(pFunc) { } \
retType Invoke(params) { \
return (*m_pFunc)(args); \
} \
private: \
retType (*m_pFunc)(params); \
} DELEGATE0(void, Test0);
DELEGATE1(void, Test1, int);
DELEGATE2(void, Test2, int, int); void print(){
printf("Just 0 arg test\n");
} int main(int argc, char *argv[])
{
AF af;
BF bf;
/*
(af.*pFunc)(10);
AF *paf = &af;
(paf->*pFunc)(11); // template
DelegateHandler<AF> afT(&af, &AF::Func);
afT.invoke(3); DelegateHandler<BF> bfT(&bf, &BF::method);
bfT.invoke(4); DelegateNmemHandler<void> nMemFunc(NonmemberFunc);
nMemFunc.invoke(5);
*/
/*
DelegateHandlerChild<AF> ac(&af, &AF::Func);
DelegateHandlerChild<BF> bc(&bf, &BF::method);
DelegateNmemHandlerChild<void> vc(NonmemberFunc); vector<IDelegateHandler *> handler;
handler.push_back(&ac);
handler.push_back(&bc);
handler.push_back(&vc); for(auto iter = handler.begin(); iter != handler.end(); iter++)
(*iter)->invoke(8);
*/ Test0<void> t0(print);
t0.Invoke(); Test1<AF> test(&af, &AF::Func);
test.Invoke(); Test1<void> tet(NonmemberFunc);
tet.Invoke(); return ;
}

使用宏定义

C++委托模式的更多相关文章

  1. 用java语言实现事件委托模式

    http://blog.csdn.net/yanshujun/article/details/6494447 用java语言实现事件委托模式 2010-04-27 00:04 2206人阅读 评论(1 ...

  2. iOS中常见的设计模式——单例模式\委托模式\观察者模式\MVC模式

    一.单例模式 1. 什么是单例模式? 在iOS应用的生命周期中,某个类只有一个实例. 2. 单例模式解决了什么问题? 想象一下,如果我们要读取文件配置信息,那么每次要读取,我们就要创建一个文件实例,然 ...

  3. ios专题 - 委托模式实现

    在ios中,委托模式非常常见,那委托模式是什么? 委托模式是把一个对象把请求给另一个对象处理. 下面见例子: #import <UIKit/UIKit.h> @protocol LQIPe ...

  4. 设计模式--委托模式C++实现

    原文章地址:http://www.cnblogs.com/zplutor/archive/2011/09/17/2179756.html [委托模式 C++实现] 我对.Net的委托模型印象很深刻,使 ...

  5. PHP设计模式之委托模式

    委托模式: 通过分配或委托至其他对象,委托设计模式能够去除核心对象中的判决和复杂的功能性. class Bank{ protected $info; /* 设置基本信息 @param string $ ...

  6. IOS常用设计模式之委托模式

    对于iOS开发,举例Cocoa框架下的几个设计模式为大家分析.当然,Cocoa框架下关于设计模式的内容远远不止这些,我们选择了常用的几种:单例模式.委托模式.观察者模式.MVC模式. 委托模式 委托模 ...

  7. classloader加载的双亲委托模式

    要深入了解ClassLoader,首先就要知道ClassLoader是用来干什么的,顾名思义,它就是用来加载Class文件到JVM,以供程序使用 的.我们知道,java程序可以动态加载类定义,而这个动 ...

  8. [js高手之路]设计模式系列课程-委托模式实战微博发布功能

    在实际开发中,经常需要为Dom元素绑定事件,如果页面上有4个li元素,点击对应的li,弹出对应的li内容,怎么做呢?是不是很简单? 大多数人的做法都是:获取元素,绑定事件 <ul> < ...

  9. 再起航,我的学习笔记之JavaScript设计模式28(委托模式)

    ## 委托模式 ### 概念介绍 **委托模式(Entrust): **多个对象接收并处理同一请求,他们将请求委托给另一个对象统一处理请求. ### 利用委托优化循环 如果我们有一个需求需要让用户点击 ...

  10. Java类加载双亲委托模式优点

    启动类加载器可以抢在标准扩展类加载器之前去装载类,而标准扩展类装载器可以抢在类路径加载器之前去加载那个类,类路径装载器又可以抢在自定义类装载器之前去加载类.所以Java虚拟机先从最可信的Java核心A ...

随机推荐

  1. kvm虚拟化二: 字符界面管理及 无人值守安装

    1. 安装必要工具yum install / tigervnc //vnc远程桌面客户端 virt-viewer //虚拟机查看器 2.安装虚拟机virt-install / -n 名字 //虚拟机名 ...

  2. ASP.NET多行文本框限制字符个数

    asp.net中TextBox当设置TextMode = Multiline时,其MaxLength属性无效.可使用JS进行辅助限制输入的字符个数.中文算两个字符,西文算1个字符. TextBox属性 ...

  3. QT要点

    1. QT设计器最终会被解释为ui_**.h. 2. QString与init之间的转换: QString转int: bool bIsOk; int a = str.toInt( &bIsOk ...

  4. 老项目迁移到springboot之后,上线服务器出现404的解决方法

    原因是老项目迁移到springboot之后,已经不再使用web.xml的配置了,但是WEB-INF目录下还有web.xml,所以才导致的404,所以只需要在源码处删除整个WEB-INF重新build即 ...

  5. Neo4j 第四篇:使用C#更新和查询Neo4j

    本文使用的IDE是Visual Studio 2015 ,驱动程序是Neo4j官方的最新版本:Neo4j Driver 1.3.0 ,创建的类库工程(Project)要求安装 .NET Framewo ...

  6. 设计模式 笔记 组合模式 Composite

    //---------------------------15/04/16---------------------------- //Composite 组合模式----对象结构型模式 /* 1:意 ...

  7. npm install的几种命令形式区别

    转自未来与传说.jigetage 我们在使用 npm install 安装模块的时候 ,一般会使用下面这几种命令形式: npm install moduleName # 安装模块到项目目录下 npm ...

  8. 【Unity Shader】从NDC(归一化的设备坐标)坐标转换到世界坐标的数学原理

    从NDC(归一化的设备坐标)坐标转换到世界坐标要点 参考资料 How to go from device coordinates back to worldspace http://feepingcr ...

  9. mssql循环记录之while方法

    1.定义变量 Declare @i Int 2.获取单条记录 Select @i=Min([id]) From [数据库名] Where <检索条件> 3.While循环 While @i ...

  10. 作业 20181204-5 Final阶段贡献分配规则及实施

    此作业要求参见:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2479] 小组介绍 组长:付佳 组员:张俊余 李文涛 孙赛佳 田良 于洋 ...