希望想理解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. WPF编程,获取句柄将外部程序嵌入到WPF界面。

    原文:WPF编程,获取句柄将外部程序嵌入到WPF界面. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details ...

  2. EZ 2018 05 06 NOIP2018 慈溪中学集训队互测(五)

    享受爆零的快感 老叶本来是让初三的打的,然后我SB的去凑热闹了 TM的T2写炸了(去你妹的优化),T1连-1的分都忘记判了,T3理所当然的不会 光荣革命啊! T1 思维图论题,CHJ dalao给出了 ...

  3. 第二十九章 springboot + zipkin + mysql

    zipkin的数据存储可以存在4个地方: 内存(仅用于测试,数据不会持久化,zipkin-server关掉,数据就没有了) 这也是之前使用的 mysql 可能是最熟悉的方式 es Cassandra ...

  4. NodeJs学习一NodeJs初识

    一.前言 按照惯例,先扯淡,就因为这货,现在才有了各大公司招聘的全栈工程师,正是因为它,让以前只会写前端的人也能写起后端服务器代码来了.所以呢,你招一个会NodeJs的前端,它都能把后端干了,一个人干 ...

  5. 虚拟机console基础环境部署——工作目录准备

    1. 概述2. 相关约定2.1 删除旧文件2.2 创建全局共享文件目录2.3 创建全局软件安装目录2.4 创建数据放置目录3. 总结 1. 概述 上述博客中,已经为console最小化安装了操作系统. ...

  6. Js_特效II

    字号缩放 让文字大点,让更多的用户看的更清楚.(也可以把字体变为百分比来实现)<script type="text/javascript">  function doZ ...

  7. Hyperledger Fabric网络节点架构

    Fabric区块链网络的组成  区块链网络结构图 区块链网络组成 组成区块链网络相关的节点 节点是区块链的通信主体,和区块链网络相关的节点有多种类型:客户端(应用).Peer节点.排序服务(Orde ...

  8. 1083. List Grades (25)-简单的排序

    给定区间[L,R],给出在这区间之内的学生,并且按照他们的成绩非升序的顺序输出. #include <iostream> #include <cstdio> #include ...

  9. ajax请求超时判断(转载)

    ajax请求时有个参数可以借鉴一下 var ajaxTimeOut = $.ajax({ url:'', //请求的URL timeout : 1000, //超时时间设置,单位毫秒 type : ' ...

  10. 20135202闫佳歆--week5 分析system_call中断处理过程--实验及总结

    week 5 实验:分析system_call中断处理过程 一.使用gdb跟踪分析一个系统调用内核函数(上周选择那一个系统调用)--getpid 复习视频: 如何实现? - 更新menu代码到最新版 ...