游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2664|回复: 6

第4版 非静态类成员函数指针 解决方案,支持BC/VC/GC/WC,

[复制链接]

2万

主题

2万

帖子

6万

积分

论坛元老

Rank: 8Rank: 8

积分
66489
QQ
发表于 2007-3-1 12:02:00 | 显示全部楼层 |阅读模式
已根据朋友建议,将汇编改为使用union,所以此次兼容性得到了大幅提高。

支持Borland/CodeGear,Microsoft,GNU,Watcom/OpenWatcom四种C/C++编译器,
在Turbo C++ 2006,Visual C++ 2005,Dev-C++ 4.9,OpenWatcom C/C++ 1.6下测试通过。
       

  1. #include<stdio.h>
  2. #include<stddef.h>
  3.        
  4. class _Object{};
  5. typedef void (_Object::*ObjectMemberFunc)(void);
  6.        
  7. #if defined(SetEventCall)||defined(CallEvent)||defined(DefineEvent)
  8.         #error SetEventCall,CallEvent,DefineEvent 已经定义
  9. #endif//
  10.        
  11. #ifdef __BORLANDC__
  12.        
  13.         #define        SetEventCall(event_obj,obj,event_func)                        event_obj=obj->event_func
  14.         #define CallEvent(event_obj)                                                    event_obj
  15.         #define DefineEvent(result,name,intro)                                    result (__closure *name)intro
  16.        
  17. #else
  18.        
  19.         #ifdef _MSC_VER
  20.                 #pragma warning(disable:4311)                //Microsoft C/C++ 警告
  21.         #endif//
  22.        
  23.         template <typename T> struct EventFunc
  24.         {               
  25.                 _Object *This;
  26.        
  27.                 union
  28.                 {
  29.                         T Func;
  30.        
  31.                         ObjectMemberFunc omf;
  32.                 };
  33.         };
  34.        
  35.         #define SetEventCall(event_obj,obj,event_func)        {event_obj.This=(_Object *)(void *)obj;event_obj.omf=ObjectMemberFunc(&event_func);}
  36.        
  37.         #define CallEvent(event_obj)                                    (event_obj.This->*(event_obj.Func))                                //(*(event_obj.This).*(event_obj.Func))
  38.        
  39.         #define DefineEvent(result,name,intro)                    EventFunc<result (_Object:: *)intro> name;
  40. #endif//__BORLANDC__
  41.        
  42. class Button
  43. {
  44. public:
  45.        
  46.         DefineEvent(void,OnClick,(Button *,int));                        //定义事件,原型为: void OnClick(Button *,int)
  47.        
  48. public:
  49.        
  50.         Button()
  51.         {
  52.                 printf("Button this=%p\n",this);
  53.         }
  54.        
  55.         void TestButtonClick()
  56.         {
  57.                 CallEvent(OnClick)(this,0);                                                //呼叫OnClick,原型为: OnClick(this,0)
  58.         }
  59. };
  60.        
  61. class Test
  62. {
  63.         Button *button;
  64.        
  65. public:
  66.        
  67.         void OnButtonClick(Button *but,int)
  68.         {
  69.                 printf("Test::OnButtonClick,this=%p,but=%p\n",this,but);
  70.         };
  71.        
  72. public:
  73.        
  74.         Test()
  75.         {
  76.                 printf("Test this=%p\n",this);
  77.        
  78.                 button=new Button;
  79.        
  80.                 SetEventCall(button->OnClick,this,Test::OnButtonClick);                                //设定button->OnClick事件的处理函数为this->OnButtonClick
  81.        
  82.                 button->TestButtonClick();
  83.         }
  84. };
  85.        
  86. int main(int,char **)
  87. {
  88.         Test *test;
  89.        
  90. #ifdef __BORLANDC__
  91.         printf("Compiler: Borland C/C++ or Turbo C/C++ %d.%d%d\n",(__BORLANDC__>>8),((__BORLANDC__&0xF0)>>4),(__BORLANDC__&0x0F));
  92. #endif
  93.        
  94. #ifdef _MSC_VER
  95.         printf("Compiler: Microsoft C/C++ %.2f (Visual C/C++ %.2f)\n",_MSC_VER/100.f,_MSC_VER/100.f-6);
  96. #endif//
  97.        
  98. #ifdef __GNUC__
  99.         printf("Compiler: GNU C/C++ %D\n",__GNUC__);
  100. #endif//__GNUC__
  101.        
  102. #ifdef __WATCOMC__
  103. #if __WATCOMC__ < 1200
  104.         printf("Compiler: Watcom C/C++ %.2f\n",__WATCOMC__/100.f);
  105. #else
  106.         printf("Compiler: OpenWatcom C/C++ %.2f\n",__WATCOMC__/100.f-11);
  107. #endif//
  108. #endif//__WATCOMC__
  109.        
  110.         printf("Compile Time: %s %s\n\n",__DATE__,__TIME__);
  111.        
  112.         test=new Test;
  113.        
  114.         delete test;
  115.        
  116.         return(0);
  117. }
复制代码

25

主题

304

帖子

311

积分

中级会员

Rank: 3Rank: 3

积分
311
发表于 2007-3-1 15:25:00 | 显示全部楼层

Re:第4版 非静态类成员函数指针 解决方案,支持BC/VC/GC/WC

谢谢,又学了一招,
F2P可以不用汇编了~~

9

主题

102

帖子

343

积分

中级会员

Rank: 3Rank: 3

积分
343
发表于 2007-3-1 18:21:00 | 显示全部楼层

Re:第4版 非静态类成员函数指针 解决方案,支持BC/VC/GC/WC

你能回调多个吗?
比如一个按钮的Click事件的回调函数有多个。
其实不用汇编。用template反而麻烦。
http://bbs.gameres.com/showthread.asp?threadid=73510

2万

主题

2万

帖子

6万

积分

论坛元老

Rank: 8Rank: 8

积分
66489
QQ
 楼主| 发表于 2007-3-1 19:21:00 | 显示全部楼层

Re:第4版 非静态类成员函数指针 解决方案,支持BC/VC/GC/WC

回调多个是何意?请详细说明

248

主题

2674

帖子

2702

积分

金牌会员

Rank: 6Rank: 6

积分
2702
QQ
发表于 2007-3-3 01:45:00 | 显示全部楼层

Re:第4版 非静态类成员函数指针 解决方案,支持BC/VC/GC/WC

很特别,值得研究.

9

主题

102

帖子

343

积分

中级会员

Rank: 3Rank: 3

积分
343
发表于 2007-12-23 20:50:00 | 显示全部楼层

Re:第4版 非静态类成员函?刚?解决方案,支持BC/VC/GC/WC,无

注意:
我发现,即使这样做,仍然需要使用汇编!

假如有一个类,使用了多继承(包括接口多继承!这是最可恶的!)
CMyClass:public Base1,public Base2
void CMyClass::Func(void);//这个函数是唯一的!基类里面没有!

然后
omf = (ObjectMemberFunc)&CMyClass::Func()
就出错。所以只有用汇编!

我已经解决了。
为了方便,我现在也使用了template。
另外我只支持类的动态成员。但是仍然需要汇编。
而且返回值必须是void
--->因为我比较懒
(不过,从VB6的实际经验来看,不需要支持返回值和也基本不需要静态成员)

9

主题

102

帖子

343

积分

中级会员

Rank: 3Rank: 3

积分
343
发表于 2007-12-23 20:52:00 | 显示全部楼层

Re: Re:第4版 非静态类成员函数指针 解决方案,支持BC/VC/GC

hyzboy: Re:第4版 非静态类成员函数指针 解决方案,支持BC/VC/GC/WC,无汇编

回调多个是何意?请详细说明


就是在多个类中接受同一个控件的事件。
在VB里遇到过这种情况的。

不过,这种情况比较少,所以我使用了动态数组而不是链表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-17 20:14

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表