游戏开发论坛

 找回密码
 立即注册
搜索
查看: 13011|回复: 10

非静态类成员函数指针解决方案 (含Borland版与Microsoft版)

[复制链接]

2万

主题

2万

帖子

6万

积分

论坛元老

Rank: 8Rank: 8

积分
66489
QQ
发表于 2007-1-5 14:38:00 | 显示全部楼层 |阅读模式
http://my.opera.com/hyzgame/blog/show.dml/648903

又做了下排版,直接LOOK和COPY都可以保持正常排版了,请刷新访问


#include<stdio.h>
#include<stddef.h>

class _Object{};

#if defined(SetEventCall)||defined(CallEvent)||defined(DefineEvent)
    #error SetEventCall,CallEvent,DefineEvent 已经定义
#endif//

#ifdef __BORLANDC__

    #define SetEventCall(event_obj,event_func)              event_obj=event_func
    #define CallEvent(event_obj)                            event_obj
    #define DefineEvent(name,result,intro)                  result (__closure *name)intro

#else

    #pragma warning(disable:4311)

    template <typename T> struct EventFunc
    {
        unsigned __int32 this_address;
        unsigned __int32 func_address;
        
        _Object *This;
        T Func;

        EventFunc()
        {   
            this_address=offsetof(EventFunc,This);
            this_address+=(unsigned __int32)this;

            func_address=offsetof(EventFunc,Func);
            func_address+=(unsigned __int32)this;
        }
    };


    #define SetEventCall(event_obj,event_func)      {                                                           unsigned __int32 this_address=event_obj.this_address;                                                           unsigned __int32 func_address=event_obj.func_address;                                                                                                                   {                                                               __asm mov eax,this_address                                                              __asm mov ebx,this                                                              __asm mov [eax],ebx                                                             __asm mov eax,func_address                                                              __asm mov ebx,event_func                                                                __asm mov [eax],ebx                                                         }                                                       }

    #define CallEvent(event_obj)                    (event_obj.This->*(event_obj.Func))             //(*(event_obj.This).*(event_obj.Func))

    #define DefineEvent(name,result,intro)          EventFunc<result (_Object:: *)intro> name;
#endif//__BORLANDC__

class Button
{
public:

    DefineEvent(OnClick,void,(Button *,int));     //定义事件,原型为: void OnClick(Button *,int)

public:

    Button()
    {
        printf("Button this=%p\n",this);
    }

    void TestButtonClick()
    {
        CallEvent(OnClick)(this,0);               //呼叫OnClick,原型为: OnClick(this,0)
    }
};

class Test
{
    Button *button;

public:

    void OnButtonClick(Button *but,int)
    {
        printf("Test::OnButtonClick,this=%p,but=%p\n",this,but);
    };

public:

    Test()
    {
        printf("Test this=%p\n",this);

        button=new Button;

        SetEventCall(button->OnClick,OnButtonClick);              //设定button->OnClick事件的处理函数为OnButtonClick

        button->TestButtonClick();
    }
};

void main(int,char **)
{
    Test *test;

#ifdef __BORLANDC__
    printf("Compiler: Borland C/C++ or Turbo C/C++ %d.%d%d\n",(__BORLANDC__>>8),((__BORLANDC__&0xF0)>>4),(__BORLANDC__&0x0F));
#endif
#ifdef _MSC_VER
    printf("Compiler: Microsoft C/C++ %.2f (Visual C/C++ %.2f)\n",_MSC_VER/100.f,_MSC_VER/100.f-6);
#endif//

    printf("Compile Time: %s %s\n\n",__DATE__,__TIME__);

    test=new Test;

    delete test;
}



Compiler: Borland C/C++ or Turbo C/C++ 5.82
Compile Time: Dec 23 2006 17:34:48

Test this=00902D50
Button this=00902D64
Test::OnButtonClick,this=00902D50,but=00902D64


Compiler: Microsoft C/C++ 14.00 (Visual C/C++ 8.00)
Compile Time: Dec 23 2006 17:34:00

Test this=003826D0
Button this=00382700
Test::OnButtonClick,this=003826D0,but=00382700

6

主题

444

帖子

457

积分

中级会员

Rank: 3Rank: 3

积分
457
发表于 2007-1-12 17:21:00 | 显示全部楼层 |阅读模式
请教下楼上,用functor实现,限制主要是什么呢?

33

主题

544

帖子

554

积分

高级会员

Rank: 4

积分
554
发表于 2007-1-5 15:57:00 | 显示全部楼层

Re:非静态类成员函数指针解决方案 (含Borland版与Microsoft版)

哈哈,好东西;)
谢谢楼主......

85

主题

824

帖子

878

积分

高级会员

Rank: 4

积分
878
QQ
发表于 2007-1-5 16:39:00 | 显示全部楼层

Re:非静态类成员函数指针解决方案 (含Borland版与Microsoft版)

嗯嗯,
好东西,
收藏了~~

15

主题

368

帖子

406

积分

中级会员

Rank: 3Rank: 3

积分
406
发表于 2007-1-7 02:40:00 | 显示全部楼层

Re:非静态类成员函数指针解决方案 (含Borland版与Microsoft版)

字好小。看不清。

54

主题

2918

帖子

3765

积分

论坛元老

Rank: 8Rank: 8

积分
3765
QQ
发表于 2007-1-7 18:19:00 | 显示全部楼层

Re: 非静态类成员函数指针解决方案 (含Borland版与Microsoft版)

谢谢,先收下了。
这靠不靠的住啊,在任何C++编译器上都兼容吗?

另外,看了你的博客期待LZ的第一步文字冒险养成:《心跳回忆》。 [em3] [em14]

sf_20071718198.jpg

2万

主题

2万

帖子

6万

积分

论坛元老

Rank: 8Rank: 8

积分
66489
QQ
 楼主| 发表于 2007-1-7 22:02:00 | 显示全部楼层

Re: Re: 非静态类成员函数指针解决方案 (含Borland版与Microso

Jeminai: Re: 非静态类成员函数指针解决方案 (含Borland版与Microsoft版)

谢谢,先收下了。
这靠不靠的住啊,在任何C++编译器上都兼容吗?

另外,看了你的博客期待LZ的第一步文字...


只保证我例子中的两种编译器

121

主题

2029

帖子

2034

积分

金牌会员

Rank: 6Rank: 6

积分
2034
QQ
发表于 2007-1-12 16:21:00 | 显示全部楼层

Re:非静态类成员函数指针解决方案 (含Borland版与Microsoft版)

我以前也做过。老实说这个还是有点危险的。。没办法啊,相对安全的Functor实现的Delegate有限制,编译速度也不太理想,这个呢,又比较的冒险。鱼和熊掌啊~

2万

主题

2万

帖子

6万

积分

论坛元老

Rank: 8Rank: 8

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

Re:非静态类成员函数指针解决方案 (含Borland版与Microsoft版)

从技术上讲,这个代码并不危险。

因为它只将必须强制转换和不可转换的两个值用汇编复制过去,省去了必须用户手写的强制转换代码而己。

如果将汇编改成C/C++代码,则必须用户手动写入强制转换,而且必须从_Object类派生,十分麻烦。

如果真的是想又方便又直观又安全,改Borland C/C++吧!

0

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2010-9-15 22:23:00 | 显示全部楼层

Re:非静态类成员函数指针解决方案 (含Borland版与Microsoft版)

收藏好好研究下
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-6 14:54

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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