如何动态保存不同类的对象的成员函数的地址?--解决

问题的提出:

就是想要实现一个容器类,可以保存不同类型的函数地址,包括成员函数,且
是属于不同类的对象的,即类不同,对象不同,函数不同(参数与返回值相同);
如题不知把传进来的不同类的函数地址保存下来,注意:这个保存下来的地址的生命期要
和对象的生命期相同;

研究过程:

1 研究了一个晚上,发现不同函数的信息是可以保存下来的(即把函数地址当作char数组可
以保存下来,用memcpy函数可以,),但是在调用时需要去用函数的类型(即类)来规定
(或解释)这个保存的函数地址,但是类型又不知道,所以现在是可以保存却读(用)不
出来,关键就是类型不能被保存下来,不能再使用。不知有什么办法可以把类型保存下来

(唉,感觉C++的指针太不灵活了)。

2 今天研究了一天,发现解决这个问题的办法就是“委托”(Delegates),下面的文章讲的

很详细:
原文:Member Function Pointers and the Fastest Possible C++ Delegates
http://www.codeproject.com/cpp/FastDelegate.asp
中文翻译:成员函数指针与高性能的C++委托
http://blog.csdn.net/hifrog/archive/2004/07/03/33068.aspx
源代码:http://bbs.nju.edu.cn/file/Y/yangjiudan/delegate.rar

作者写了一个类用于解决C++委托问题。
我大概是这样理解的,
对于普通函数和静态成员函数应该没问题,按常规的方法就可以;
而对于非静态成员函数,其调用需要知道对象的地址T *O,对象的类型T,成员函数的
地址ReturnType (T::*menfunc)(InputType);
对象的类型可以通过函数模板得到T,则对象的地址O,成员函数的地址memfunc也就知道了

则可以通过(O->*menfunc)(InputType para);来调用此函数;
到此就可以实现调用不同类型的对象的成员函数的目的。
但是此时调用函数是即时性的,即你只能在得到函数信息的函数中去调用函数,出了此函
数,这些被调用的函数的信息就没有了,所以你不能做到用一个函数把需要被调用的函数
添加进去,再在另一个函数中去正式去调用这些添加的函数。所以此时还不能达到目的。

所以关键的问题是能把每次传入的不同类型的对象及其成员函数保存下来,也就是需要一
个对应类型的变量去存储,但是类型又不知,也不同,而通过类模板也只能知道有限种类
的类型(其实这样也行,让使用者把要用到的类型通过模板参数传入,但类型的数目是有
最大值的,然后在类内部为每一种传入类型声明一个变量用来存储添加的被调用函数的信
息,在添加函数中利用RTTI去把相应的信息存入相应的变量,在调用时利用变量的信息就
可以成功地调用该函数了,但是这样实现的方法很笨(自己想的,没办法)很不灵活),
所以只能另求他发,这就是该文作者的方法:大概是这样的,关键还在于对象信息存储,
虽然不同类型的对象的信息不同,但对于同一编译器不同类型的对象的地址和成员函数地
址的结构(构成)是相同的(只是不同类型其内容会不同而已),所以可以定义一个一般
类型(地址结构要最大),这样把其他的类型的地址信息就可以强制转换(reinter_cast
,没记错吧)并且不会丢失任何信息,这一步是通过union来实现的,这样需要的信息就保
存下来了,下面就需要读(用)出来,前面说了成员函数的调用也是需要具体类型信息的
,但现在还是没有把原类型保存下来(这是做不到的),只有转换后的类型信息,那该怎么
办呢,有东西用不了,那不就根没有一样?不对,那是因为你不会用,怎么用?像编译器
一样用,编译器是根据类型去通过对象的地址和成员函数地址的结构去最终得到真正的地
址(具体看原文),所以我们只要像编译器一样,在知道类型的时候(也就是添加函数时)
自己把真正的地址保存下来。
然后在调用时,读出真正的地址通过(*对象地址->*成员函数真正地址)(输入参数)调用相
应的函数,其实就是本该编译器做的事情,去自己作,所以可以做编译器做不了的事;还
有一点,作者实现的对函数的调用是通过函数对象来实现的(即重载()运算符),所以你
得到的函数的运行结果,而不是函数。
哎呀,真乱,不知自己的理解对不对,希望有兴趣的好好看看作者的原文和源码,
大家好好交流一下。
源码中有个demo大家可以看一下效果

问题的总结:

就是C++中的委托的实现,用boost中的function类可以(没验证),

用上面提到的Fastde Delegate也可以实现(效率高),另外CodeProject中有一类文章讲委托 (Delegates)的;

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值