有个问题想请教一下了解“委托”Delegate的牛人哈~!如果有以下的代码实现,那么,这种对于My_Delegate类的使用,是否就等价于C#中的“委托(Delegate)”?(先不考虑委托的异步调用)class CClassA
{
public:
CClassA(){m_iClassA=100;}
int m_iClassA;
void OnEventHandler(void *pSource)
{
printf("[CClassA]Event comes from source :0x%08X\n",pSource);
}
};
//CClassB、CClassC类似,省略CClassA a;
CClassB b;
CClassC c;class CClassWork
{
public:
CClassWork()
{//My_Delegate是一个C++的类,里面存储了成员函数的地址与相应的对象指针
m_dg=My_Delegate(&a,&CClassA::OnEventHandler);
m_dg+=My_Delegate(&b,&CClassB::OnEventHandler);
m_dg+=My_Delegate(&c,&CClassC::OnEventHandler);
}
void StartWork()
{
printf("Work done! Fire event!\n");
m_dg.Invoke(this);//发出事件,在事件响应链中,依次调用了CClassA、CClassB、CClassC的OnEventHandler函数。
}
protected:
My_Delegate m_dg;
};
//主函数开始
int main(int argc, char* argv[])
{
CClassWork mywork;
mywork.StartWork(); getch();
return 0;
}
c++委托Delegate
{
public:
CClassA(){m_iClassA=100;}
int m_iClassA;
void OnEventHandler(void *pSource)
{
printf("[CClassA]Event comes from source :0x%08X\n",pSource);
}
};
//CClassB、CClassC类似,省略CClassA a;
CClassB b;
CClassC c;class CClassWork
{
public:
CClassWork()
{//My_Delegate是一个C++的类,里面存储了成员函数的地址与相应的对象指针
m_dg=My_Delegate(&a,&CClassA::OnEventHandler);
m_dg+=My_Delegate(&b,&CClassB::OnEventHandler);
m_dg+=My_Delegate(&c,&CClassC::OnEventHandler);
}
void StartWork()
{
printf("Work done! Fire event!\n");
m_dg.Invoke(this);//发出事件,在事件响应链中,依次调用了CClassA、CClassB、CClassC的OnEventHandler函数。
}
protected:
My_Delegate m_dg;
};
//主函数开始
int main(int argc, char* argv[])
{
CClassWork mywork;
mywork.StartWork(); getch();
return 0;
}
c++委托Delegate
解决方案 »
- 请问一个c++中使用托管代码出现的问题?
- wincore line 993
- 下面的写入是乱码,求解决方法,我的环境是unicode
- CFIleDialog获取的路径 出现的问题
- 类数组初始化
- 请教 如何让对话框中的radio初始处于选中状态
- 如何使用DirectX播放mp3?
- 请教:VC如何往ACCESS中写入一个Function
- 小女子求助:Activex控件第一次用cab包自动注册成功,然后再通过网页调用.exe的安装程序注册就不成功,而在本机上直接运行注册也没问题,怎么回事?
- 关于readfile(...)的问题.
- 有个问题想请教一下了解“委托”Delegate的牛人哈~!
- 预处理是在VC6.0的什么时候?
{
public:
//.........
void StartWork()
{
printf("Work done! Fire event!\n");
My_Delegate theDelegate(&a,&CClassA::OnEventHandler);
theDelegate+=My_Delegate(&b,&CClassB::OnEventHandler);
theDelegate+=My_Delegate(&c,&CClassC::OnEventHandler);
MethodOfWork_Using_Delegate(theDelegate);
}
void MethodOfWork_Using_Delegate(My_Delegate & theDelegateObj)
{
theDelegateObj.Invoke(this);//发出事件,在事件响应链中,依次调用了CClassA、CClassB、CClassC的OnEventHandler函数。
}
};我参考了这里的文章:
http://www.cnblogs.com/zhili/archive/2012/10/22/Delegate.html
通常“代理模式”中代理者与被代理者具有相同的接口(他们继承自同一接口),一般代理者会包含一个该接口的指针或引用。例如:
struct IInterface
{
virtual void do() = 0;
};class A :IInterface
{
IInterface* m_pMember;
public :
A(IInterface* pObj){m_pMember = pObj;}
void do(){m_pMember->do();}
};
class B :IInterface
{
IInterface* m_pMember;
public :
void do(){cout<<"do in class B"<<endl;}
}使用时可以如下:
B b;
A a(&b);
a.do();
如此以来,对外面显示来说,都是A在做事情,但其实A什么都没做,它只是调用了其代理的b对象来完成实际的操作。对比一下你的代码,可以看出并不符合代理模式。
个人理解:
通常“代理模式”中代理者与被代理者具有相同的接口(他们继承自同一接口),一般代理者会包含一个该接口的指针或引用。例如:
struct IInterface
{
virtual void do() = 0;
};class A :IInterface
{
IInterface* m_pMember;
public :
A(IInterface* pObj){m_pMember = pObj;}
void do(){m_pMember->do();}
};
class B :IInterface
{
public :
void do(){cout<<"do in class B"<<endl;}
}使用时可以如下:
B b;
A a(&b);
a.do();
如此以来,对外面显示来说,都是A在做事情,但其实A什么都没做,它只是调用了其代理的b对象来完成实际的操作。对比一下你的代码,可以看出并不符合代理模式。
对的,CodeProject上有篇文章详细解释了函数指针与委托的关系。
http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
http://blog.csdn.net/cjl5678/article/details/7649686
大家不要跑题啊,我在这里是想讨论一下委托在C++下的实现。通过其他的模式也许能实现同样的效果,但是那不是我的目标。另外,大家一起帮忙看看,这样的用法,是否算是一种比较规范的委托的用法呢?我尽量遵循开放封闭原则了。
class CKeepManager
{
public:
CKeepManager()
{
}
void KeepPet(char* name,My_Delegate &MethodOfKeepPets)
{
MethodOfKeepPets(this,name);//通过重载“()”运算符实现。第一个参数是sender,就是C#中,事件回调函数中的那个参数sender。在这里,指明此回调的来源,就是当前对象本身。
} //////////////////////////////////////////////////////////////////////////
void KeepDogs(void* pSource,char* name)
{
printf("%s,需要到商店A买狗粮\n",name);
}
void KeepCats(void* pSource,char* name)
{
printf("%s,需要到商店B买猫粮\n",name);
}
};int main(int argc, char* argv[])
{
CKeepManager KM;
My_Delegate methodOfKeepPets(&KM,&CKeepManager::KeepDogs);//将对象实例与对象方法,关联到“委托实例”中。
//在这个例子中,有点特殊,sender与接收者都是KM对象。
KM.KeepPet("养狗",methodOfKeepPets);//将方法设置成了一个参数,传入后调用
}
对于我这种用惯了指针的人,总觉的委托这个概念怪怪的,明明就是个指针,还扭扭捏捏地不肯承认。
楼主既然在使用C++,直接使用函数指针就行了。