200分,大家来谈谈用C++实现委托,反射.委托,反射基本原理是什么?

lyg_zy 2007-07-27 05:21:41
200分,大家来谈谈用C++实现委托,反射.委托,反射基本原理是什么?近日看了看.net,java里实现的反射,委托机制,自己感觉和com里的IDispath和ITypeInfo,根据GUID创建对象很相似,欢迎大家讨论!
...全文
951 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
_程序员 2011-10-27
  • 打赏
  • 举报
回复
我也来顶一下,看有没有人继续..
rgwfeng2 2008-03-05
  • 打赏
  • 举报
回复
mark
lyg_zy 2007-08-04
  • 打赏
  • 举报
回复
大家继续讨论下,周一结贴了。
lyg_zy 2007-08-02
  • 打赏
  • 举报
回复
c++反射:
基本原理:
实际上就是根据一字符串(当然字符串也可能是一ID或GUID什么的),可以创建对象,可以
得到设置对象里的某个变量的值。
根据一字符串(函数名)和对应的参数列表,可以调用对象里的某个函数。
MFC实现:
根据字符串("类名")可以创建对象,通过CRuntimeClass和CObject类。mfc只实现了
这一部分:
COM实现:
根据GUID(类ID CLASSID和 接口ID IID)就可以创建一接口对象,通过CoCreateInstance函数
通过实现IDispatch自动化接口,就可以对一接口对象的所有的方法属性进行枚举,并且
可以通过IDispatch::Invoke函数就可以通过字符串(属性名,函数ID,函数名,
函数参数列表)就可以对接口内的属性,方法进行后期绑定调用。
.net的实现:
大家补充
java的实现:
大家补充
lyg_zy 2007-08-02
  • 打赏
  • 举报
回复
c++委托:
基本原理
实际上就是函数回调包装(包括成员函数和全局函数).
COM实现:
连接点事件机制,不过COM里是接口回调。
.net实现:
大家补充
java实现:
大家补充
yiliang18 2007-08-02
  • 打赏
  • 举报
回复
学习
美丽海洋 2007-08-02
  • 打赏
  • 举报
回复
我们知道了C#中委托的原理,是不是也可以在C++中实现呢?答案是肯定的。不同的是C#在语言级别提供了对委托的支持,而C++没有,它需要我们对委托进行定制。这样,每种不同形式的委托都要有不同的实现,灵活性大打折扣。幸运的是,作者已经提供了一个名为delegate.exe的实用小工具,它可以帮我们实现由委托声明生成实际代码。其用法将在后面详细介绍。
下面是运行示例:

#include "Delegate.h"

#include <iostream>

#include <windows.h>



void Say1(char *s)

{

cout<<"In Function Say1: ";

cout<<s<<endl;

}

void Say2(char *s)

{

cout<<"In Function Say2: ";

cout<<s<<endl;

}

void STHeoaie(char *s)

{

MessageBox(NULL,s,"Delegate",MB_OK);

}

void main()

{

CDelegate dlg;

dlg.AddFunction(Say1);

dlg.AddFunction(Say2);

dlg+=STHeoaie;

int rs=dlg.Invoke("Hello,World!");

if(!rs) cout<<"Failed."<<endl;

/*

第一次调用结果:





*/

dlg-=Say2;

rs=dlg("The second invoking by CDelegate!");

file://等同于dlg. Invoke("The second invoking by CDelegate!")

if(!rs) cout<<"Failed."<<endl;

/*

第二次调用:





*/

dlg-=Say1;

dlg-=STHeoaie;

rs=dlg.Invoke("The Third invoking by CDelegate!");

if(!rs) cout<<"Failed."<<endl;

/*

第三次调用,没有任何输出,因为已注销所以方法:



*/

}



3.关于实用小工具delegate.exe

为了解决在定制委托时的不灵活性,我特意编写了这个小工具,它能够方便地将委托声明转化为如上面所述的代码。下面是其基本用法。

在你的某个头文件中,如test.h,以__delegate关键字声明一个委托:

__delegate void WinHandler ( HWND hwnd ,UINT message ,WPARAM wParam,LPARAM lParam);

然后转到命令行模式,进入test.h的目录,键如如下命令:

delegate.exe test.h /out test.hxx

它将生成test.hxx文件。你可以向你的源程序中包含这个文件,以使用你所定义的委托。如,可以是这样:#include “test.hxx”

你可以在一个文件里定义多个委托,也可以在多个文件里定义多个委托.但是你只能指定一个的输出文件.如果你没有用/out选项指定输出文件,则默认输出为delegate.h。如:

delegate.exe test.h test1.h test2.h /out test.hxx

使用/help选项得到帮助信息,使用/version选项得到版本信息.



注意:最新的Visual C++ .Net 版本已经支持同名关键字 __delegate,这是微软公司为了将Visual C++向.net移植而添加的新关键字,只有 Visual C++ .Net 支持,其他如Visual C++ 6.0、Borland C++ Builder 、GNU C++ 等都不支持。但两个完全没有联系.幸运的是,delegate小工具支持/keyword选项,它可以指定你自己定义的关键字,如__delegate__。
美丽海洋 2007-08-02
  • 打赏
  • 举报
回复
你如果对C#语言比较了解的话,就应该会知道C#语言中有一个很好的特性,那就是委托。它能够大大简化在某些特定的场合调用多个相同形式函数的处理。特别是在像Windows程序中,用委托响应消息十分方便。举一个常见的例子。现在的Windows应用程序框架都比较复杂,一个应用程序可能由许多部件组成,很多时候它们都需要响应同一个消息。如在一个MDI中,多个子窗体都要响应主窗体的WM_QUIT消息。很多时候,我们并不需要像MFC那样将所有的处理都封装在类中,我们需要一种简单易用的方法,直观地解决这个问题。这篇文章为你提供了这样的方法。

在C#中,处理消息的委托被定义为如下格式:

public delegate void WinEventHandler(object sender, EventArgs arg);

假设在一个MDI中,主窗体由MainFrame实现。我们在主窗体定义一个专门用于处理WM_QUIT消息:

public event WinEventHandler OnQuit;

在上面的声明中,public表明该委托可以在外部访问(注册/删除),event关键字表明这是一个事件,只能在类内部调用,外部不能直接触发它。在MainFrame的窗体过程函数中,WM_QUIT消息是这样被分发的:

protected virtual void WndProc(Message msg,object sender,EventArgs arg)

{

......

switch(msg)

{

......

case WM_QUIT:

OnQuit(sender,arg);

break;

......

}

}

那么,MainFrame的子窗体如何响应主窗体的WM_QUIT消息呢?首先,你要实现子窗体Child1处理该消息的函数,它的声明形式要跟WinEventHandler委托相同:

//In Child1 Class

protected void Child1_On_Quit(object sd, EventArgs ags)

{

this.SaveAll(); file://做些善后工作,如保存当前信息等

……

}

在子窗体被初始化时向MainFrame的OnQuit委托注册这个函数。如果MainFrame是Child1的父窗体,那么其实现可能是这样的:

parent.OnQuit += new WinEventHandler(this.Child1_On_Quit);

这样,当MainFrame收到WM_QUIT消息时,调用OnQuit委托,同时Child1.Child1_On_Quit也被调用,从而实现消息传递。当然,也有子窗体不再需要响应主窗体的WM_QUIT消息的时候。我们可以通过下面的方式从MainFrame的OnQuit委托中注销它:

parent.OnQuit -= new WinEventHandler(this.Child1_On_Quit);

这一步也是很必要的。如果Child1先于主窗体MainFrame被摧毁,而Child1_On_Quit没有从MainFrame.OnQuit委托中注销,则主窗体收到WM_QUIT消息时调用OnQuit委托,它又顺序调用到Child1.Child1_On_Quit,则可能引发空引用异常了。[详细介绍,请参见《IL代码底层运行机制:函数相关]

委托可以接受多个实例方法,因此你可以向一个委托注册多个方法。实际上,委托包含了一个方法引用的列表,当委托被调用时,它将顺序调用其列表中的方法引用。这一点我还会在后面详细说明。



2.在C++中实现委托
我们知道了C#中委托的原理,是不是也可以在C++中实现呢?答案是肯定的。不同的是C#在语言级别提供了对委托的支持,而C++没有,它需要我们对委托进行定制。这样,每种不同形式的委托都要有不同的实现,灵活性大打折扣。幸运的是,作者已经提供了一个名为delegate.exe的实用小工具,它可以帮我们实现由委托声明生成实际代码。其用法将在后面详细介绍。
我们知道了C#中委托的原理,是不是也可以在C++中实现呢?答案是肯定的。不同的是C#在语言级别提供了对委托的支持,而C++没有,它需要我们对委托进行定制。这样,每种不同形式的委托都要有不同的实现,灵活性大打折扣。幸运的是,作者已经提供了一个名为delegate.exe的实用小工具,它可以帮我们实现由委托声明生成实际代码。其用法将在后面详细介绍。
美丽海洋 2007-08-02
  • 打赏
  • 举报
回复
楼主可以说一下你自己的看法;在.net java是怎么实现的?
stonehe 2007-08-02
  • 打赏
  • 举报
回复
我也很想知道啊
KKND2006 2007-08-01
  • 打赏
  • 举报
回复
lz的问题

在候捷的<深入浅出MFC>的前几章就有很详细的叙述了

建议LZ去好好读读这本书,了解一些VC内部原理
vcnewer 2007-08-01
  • 打赏
  • 举报
回复
chang_an_liu 2007-08-01
  • 打赏
  • 举报
回复
C#中的委托确实可以使用C++实现,(也已经有人实现了-- 由于产权保护,我就不说出处了)。
主要原理是:
1。 定义自己的Mehtod,用来相应事件,这个可以使用模版类实现,两个参数,一个相应事件的类名,另一个是这个类中的函数成员。
2。 定义自己的Event,也是使用模版类来做。
3。 使用了观察者模式,做一个全局的管理类。将一个Event和Method捆绑起来,应用观察者模式。
lyg_zy 2007-08-01
  • 打赏
  • 举报
回复
还有人来谈谈吗?过两天结贴了!
emptyness 2007-07-30
  • 打赏
  • 举报
回复
UP ..
lyg_zy 2007-07-30
  • 打赏
  • 举报
回复
顶一下。
兔子-顾问 2007-07-28
  • 打赏
  • 举报
回复
.
兔子-顾问 2007-07-28
  • 打赏
  • 举报
回复
Event.h

//event.h
#include <afxtempl.h>
template <typename Handler>
class event
{
private:
CArray<Handler,Handler> m_HandlerList;
protected:
//模拟C# event 的add/remove访问器
//如果要重新实现add/remove请在派生类中重写这两个函数
virtual void add(Handler value)
{
m_HandlerList.Add(value);
};
virtual void remove(const Handler value)
{
int nCount = m_HandlerList.GetSize();
for (int i = 0;i < nCount;i++)
{
if (value == m_HandlerList[i])
{
m_HandlerList.RemoveAt(i);
break;
}
}
};
public:
//构造函数
event(){}
//+= 操作符
event& operator += (const Handler value)
{
add(value);
return *this;
}
//-=操作符
event& operator -= (const Handler value)
{
remove(value);
return *this;
}

//PFN_EVENT_HANDLE 操作符
CArray<Handler,Handler>& GetEvent()
{
return m_HandlerList;
}
};

/**********************************************************/
我的类
//MyClass.h
#include "event.h"
//定义EventHandler的函数指针类型
typedef void(*EventHandler)();

class MyClass
{
public:
//构造函数
MyClass(){};
//声明一个事件
event<EventHandler> AEvent;
//激发事件
void FireEvent()
{
int nCount = AEvent.GetEvent().GetSize();
for (int i=0;i<nCount;i++)
{
((EventHandler)AEvent.GetEvent().GetAt(i))();
}
//C++中必须用EventHandler进行强制类型转换
// ((EventHandler)AEvent)();

}
};

/**********************************************************************/
使用
// cppevent.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include "MyClass.h"
//向前声明
void MyEventHandler();

int main(int argc, char* argv[])
{
MyClass Obj;
Obj.AEvent += MyEventHandler;//定制事件
Obj.FireEvent();//这行将导致MyEventHandler被调用

Obj.AEvent -= MyEventHandler;//撤消事件
Obj.FireEvent();//这个将不会引发事件

printf("结束!\n");
char n;
scanf("%c", &n);
return 0;
}

void MyEventHandler()
{
printf("This is a event!\n");
}
luohongming 2007-07-28
  • 打赏
  • 举报
回复
进来向高手学习.
hoya5121 2007-07-28
  • 打赏
  • 举报
回复
如果发在设计模式板块可能会好点
加载更多回复(11)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧