CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

高分求实现方法

楼主sevecol(sevecol.blogone.net)2001-09-24 17:40:29 在 C/C++ / C语言 提问

不论用什么方法将一个指向类成员函数的指针,赋给一般函数指针,并且调用成功。  
  例子:  
  class   A  
  {  
  public:  
          int   t;  
          void   print(){cout<<i<<endl;};  
  };  
  //  
  .....  
  如何用一个指向一般函数的指针来调用print. 问题点数:280、回复次数:28Top

1 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 17:41:12 得分 0

补充一句,可以用任何方法Top

2 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 17:48:02 得分 0

upTop

3 楼Jneu(沧海桑田)回复于 2001-09-24 17:48:18 得分 0

upTop

4 楼Jneu(沧海桑田)回复于 2001-09-24 17:48:27 得分 0

upTop

5 楼Jneu(沧海桑田)回复于 2001-09-24 17:48:36 得分 0

upTop

6 楼cber(cber)回复于 2001-09-24 17:50:12 得分 90

转贴bugn所写的“用template   partial   specialization模拟borland   C++中的closure类型函数指针”  
   
  #include   <iostream>  
  #include   <utility>  
   
  using   namespace   std;  
   
  //  
  //   a   simulation   for   the   closure   keyword   in   borland   c++   compiler  
  //  
  //   written   by   bugn,   Feb   8,   2001  
  //  
   
  template   <typename   T> //   traits   class  
  struct   MemFuncTraits   {};  
   
  template   <typename   R,   typename   O> //   partial   specialization  
  struct   MemFuncTraits<R   (O::*)()>   { //   for   zero-parameter  
  typedef   R   ReturnType; //   non-const   member  
  typedef   O   ObjectType; //   functions  
  };  
   
  template   <typename   R,   typename   O> //   partial   specialization  
  struct   MemFuncTraits<R   (O::*)()   const>   { //   for   zero-parameter  
  typedef   R   ReturnType; //   const   member  
  typedef   O   ObjectType; //   functions  
  };  
   
  template   <typename   R,   typename   O,   typename   P1> //   partial   specialization  
  struct   MemFuncTraits<R   (O::*)(P1)>   { //   for   one-parameter  
  typedef   R   ReturnType; //   non-const   member  
  typedef   O   ObjectType; //   functions  
  };  
   
  template   <typename   R,   typename   O,   typename   P1>   //   partial   specialization  
  struct   MemFuncTraits<R   (O::*)(P1)   const>   { //   for   one-parameter  
  typedef   R   ReturnType; //   const   member  
  typedef   O   ObjectType; //   functions  
  };  
   
  template   <typename   R,   typename   O,   typename   P1,   typename   P2> //   partial   specialization  
  struct   MemFuncTraits<R   (O::*)(P1,P2)>   { //   for   two-parameter  
  typedef   R   ReturnType; //   non-const   member  
  typedef   O   ObjectType; //   functions  
  };  
   
  template   <typename   R,   typename   O,   typename   P1,   typename   P2>   //   partial   specialization  
  struct   MemFuncTraits<R   (O::*)(P1,P2)   const>   { //   for   two-parameter  
  typedef   R   ReturnType; //   const   member  
  typedef   O   ObjectType; //   functions  
  };  
   
  //   u   can   extend   MemFuncTraits   to   support   more   parameters  
  //  
   
  template   <typename   MemFuncPtrType>  
  struct   Closure   {  
  public:  
  typedef   typename   MemFuncTraits<MemFuncPtrType>::ObjectType   ObjectType;  
  typedef   typename   MemFuncTraits<MemFuncPtrType>::ReturnType   ReturnType;  
  typedef   pair<ObjectType*,   MemFuncPtrType>   CallInfo;  
   
  Closure(ObjectType*   pobj,   MemFuncPtrType   ptr_fun)   :   call_info(make_pair(pobj,   ptr_fun)){  
  }  
   
  Closure&   bind(ObjectType*   pobj,   MemFuncPtrType   ptr_fun)   {  
  call_info.first   =   pobj;  
  call_info.second   =   ptr_fun;  
  }  
   
  //   NOTE!   the   following   assignment   operator   must   be   used   with   caution   !  
  Closure&   operator=(MemFuncPtrType   ptr_fun)   {  
  call_info.second   =   ptr_fun;  
  }  
   
  //   NOTE!   the   following   assignment   operator   must   be   used   with   caution   !  
  Closure&   operator=(ObjectType*   pobj)   {  
  call_info.first   =   pobj;  
  }  
   
  //   support   for   0   parameters  
  ReturnType   operator()()   const   {  
  return   (call_info.first->*call_info.second)();  
  }  
   
  //   support   for   1   parameter  
  template   <typename   Param1Type>  
  ReturnType   operator()(Param1Type   p1)   const   {  
  return   (call_info.first->*call_info.second)(p1);  
  }  
   
  //   support   for   2   parameter2  
  template   <typename   Param1Type,   typename   Param2Type>  
  ReturnType   operator()(Param1Type   p1,   Param2Type   p2)   const   {  
  return   (call_info.first->*call_info.second)(p1,   p2);  
  }  
   
  //   u   can   extend   it   to   support   more   parameters  
  //  
   
  private:  
  CallInfo call_info;  
  };  
   
   
  //  
  //   the   following   is   a   simple   test   for   our   closure   template  
  //  
   
  struct   Wombat   {    
  virtual   int   dig(short   cid)  
  {  
  cout   <<   "["   <<   cid   <<   "]   "   <<   "Wombat   digging...\n";  
  return   1;  
  }    
  int   sleep(short   cid)  
  {  
  cout   <<   "["   <<   cid   <<   "]   "   <<   "Wombat   sleeping...\n";  
  return   5;  
  }  
  };  
   
  struct   BabyWombat   :   public   Wombat   {  
  int   dig(short   cid)  
  {  
  cout   <<   "["   <<   cid   <<   "]   "   <<   "Baby   wombat   digging...\n";  
  return   1;  
  }    
  int   sleep(short   cid)  
  {  
  cout   <<   "["   <<   cid   <<   "]   "   <<   "Baby   wombat   sleeping...\n";  
  return   5;  
  }  
  };  
   
  void   main()  
  {  
  Wombat wb;  
  BabyWombat baby;  
   
  typedef   int   (Wombat::*PWMF)(short); //   pointer   to   a   Wombat   member   function  
   
  Closure<PWMF> fp(&wb,   &Wombat::dig);  
  fp(1);  
   
  fp   =   &Wombat::sleep;  
  fp(2);  
   
  fp   =   &baby;  
  fp(3);  
   
  fp   =   &Wombat::dig;  
  fp(4);  
   
  fp   =   (PWMF)&BabyWombat::sleep;  
  fp(5);  
  }  
   
  Top

7 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 18:00:42 得分 0

厉害厉害,不是看得很仔细,我想你是用一个类来模拟指针,也就是说并不是真正的将  
  两个指针互相转化吧,不知道我说的对不对,见笑了Top

8 楼tohigh(岁月的童话.NET)回复于 2001-09-24 18:21:51 得分 0

学习.Top

9 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 18:56:08 得分 0

可以用任何方法,upTop

10 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 19:17:05 得分 0

upTop

11 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 19:52:03 得分 0

upTop

12 楼Only_I(我)回复于 2001-09-24 20:22:14 得分 0

请问i在哪里?Top

13 楼sevecol(sevecol.blogone.net)回复于 2001-09-24 21:37:17 得分 0

你自己可以产生一个实例  
  A   a;然后调用Top

14 楼handsome1234(我太菜了,)回复于 2001-09-24 23:31:45 得分 0

heheTop

15 楼cker(〖烟波浩淼三千里、人鬼殊途五百年〗)回复于 2001-09-24 23:54:00 得分 90

#include   <stdio.h>  
  class   CBase  
  {  
  public:  
          CBase();  
          virtual   ~CBase();  
          void   Fun1(int   n);  
          void   Fun2(int   n);  
          void   Fun3(int   n);  
   
  };  
   
  CBase::CBase(){};  
  CBase::~CBase(){};  
   
  void   CBase::Fun1(int   n)  
  {  
          printf("FUN1   :   Hello   World!     %d\n",n);  
  };  
  void   CBase::Fun2(int   n)  
  {  
          printf("FUN2   :   Hello   World!     %d\n",n);  
  };  
  void   CBase::Fun3(int   n)  
  {  
          printf("FUN3   :   Hello   World!     %d\n",n);  
  };  
   
  typedef   void   (CBase::*BaseMemberFn)(int);  
  #define   CallMemberFun(object,ptrToMember)     ((object).*(ptrToMember))  
  int   main(int   argc,   char*   argv[])  
  {  
          BaseMemberFn   FnArray[3]={&CBase::Fun1,&CBase::Fun2,&CBase::Fun2};  
          CBase   b;  
          for(int   i=0;i<3;i++)   CallMemberFun(b,FnArray[i])(i);  
          getchar();  
          return   0;  
  }Top

16 楼cker(〖烟波浩淼三千里、人鬼殊途五百年〗)回复于 2001-09-24 23:56:18 得分 0

用static   申明此成员函数也是可行的办法。  
  Top

17 楼qqchen79(知秋一叶)回复于 2001-09-25 03:17:40 得分 100

是你说不择手段的!我就不管了。  
  对一下程序:  
      1.   member   function   must   not   be   virtual.  
      2.   member   function   cannot   depend   on   value   of   this.  
      3.   prepare_cast   只是用来定义变量,如果愿意,把它并在第二个define里。  
      4.   没法保证不出错。  
   
  #include   "stdafx.h"  
  #include   <iostream>  
   
  using   namespace   std;  
   
  #define   prepare_cast char   _strange_cast_buf[64]  
  #define   strange_cast(t,   f) (sprintf(_strange_cast_buf,   "%d",   f),   (t)atoi(_strange_cast_buf));  
   
  struct   A    
  {  
  void   foo()   {  
  cout   <<   "Class   A::foo()"   <<   endl;  
  }  
  };  
   
  typedef   void   (*FUNC)(void);  
   
  int   main()  
  {  
  prepare_cast;  
  FUNC   func   =   strange_cast(FUNC,   A::foo);  
  func();  
  return   0;  
  }  
  Top

18 楼sevecol(sevecol.blogone.net)回复于 2001-09-25 09:05:01 得分 0

to   cker:你的方法是其实只是表面上不是调用指向成员函数的指针,实际上还是调用了,用static那就不是成员函数了  
  to   qqchen79:方法不错,虽然没有调试,但是我觉得有问题,你的函数里面没有调用struct里面  
  数据,也就是说你的函数不依赖于实例,但是如果依赖实例呢,那用你的方法我觉得有问题  
  我的想法是将typedef   void(*FUNC)();改为typedef   void   (*FUNC)(A&);应该OK  
  Top

19 楼cber(cber)回复于 2001-09-25 09:17:05 得分 0

to   sevecol:用一个function   object来代替函数指针没有什么不好的。如果非要用函数指针之间的转换,我也没有办法:(Top

20 楼sevecol(sevecol.blogone.net)回复于 2001-09-25 09:34:40 得分 0

to   cber:我只是想看看还有什么好的办法,我觉得用function   object来使用的话,开销会不会太大了?如果使用很多的话?Top

21 楼wilddragon(东瀛倭族自治州州长)回复于 2001-09-25 10:00:46 得分 0

哈哈Top

22 楼qqchen79(知秋一叶)回复于 2001-09-25 10:55:10 得分 0

 
      事实上a.foo()与foo(A&   a)完全不一样,前者将this放在ecx寄存器里(Intel   CPU的转换),后者将a的地址放在堆栈里,所以直接的转换不可能存在(如果前汇编的话,也许能行,但也不一定符合你的要求了)Top

23 楼qqchen79(知秋一叶)回复于 2001-09-25 10:57:40 得分 0

顺便说一句,STL中有个mem_fun的adaptor,就实现了cber的方法。而且一般用functor对象不会慢。Top

24 楼sevecol(sevecol.blogone.net)回复于 2001-09-25 11:17:47 得分 0

to   qqchen79:用汇编可以,我试了,谢谢你了  
  派分了Top

25 楼coldsea_2000(怒海风云)回复于 2001-09-25 21:23:51 得分 0

看着看着就花了眼,岂一个长字了得?Top

26 楼IAmKylix(kylix)回复于 2001-09-26 08:24:56 得分 0

为什么要用C++?Top

27 楼satanmonkey(撒旦)回复于 2001-09-26 10:20:17 得分 0

gzTop

28 楼city_tiger(都市老虎)回复于 2001-09-26 13:33:44 得分 0

 
   
  VC专家答疑  
  http://bros4.top263.net  
   
   
   
   
  Top

相关问题

  • 高分求 表格的实现方法
  • 高分寻找DTC算法的实现方法(C,VC,JAVA实现均可)
  • 高分求救关于用mschart实现直方图的方法.
  • 高分求挂QQ网站实现方法
  • 高分求助,如何实现等级方法?
  • 讨教实现方法,up者有分
  • 100分求救界面实现方法!!
  • 【【【600分】】】】求Word滚动实现方法
  • 高分请教数据库连接池的实现方法,在线给分!!
  • 高分求VB中分割条的实现方法或者控件

关键词

  • 指针
  • template
  • memfunctraits
  • cbase
  • membertypedef o
  • parametertypedef
  • specializationstruct
  • objecttype
  • returntype
  • fun

得分解答快速导航

  • 帖主:sevecol
  • cber
  • cker
  • qqchen79

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo