注册 登录
编程论坛 C++教室

[原创] 类的成员函数也能做成回调函数?? 能!!

flyue 发布于 2008-08-24 18:59, 4123 次点击
曾经做程序的时候想要把某个类的成员函数做成一个回调函数来用,但一直没有成功:

class CCallBack
{
public:
    // 测试的被回调的函数
    void TestFunc(int a)
    {
        printf("%d\n", a);
    }
};

void main()
{
    CCallBack cb;
    void* f = (void*)(cb.TestFunc);
}


Compiling...
test.cpp
test.cpp(85) : error C2440: 'type cast' : cannot convert from 'void (__thiscall CCallBack::*)(int)' to 'void *'
        There is no context in which this conversion is possible
执行 cl.exe 时出错.

(曾经问过StarWing,他说这是不可能实现的

后来找了好多资料,终于被我发现了,原来类函数的回调并非不可实现。居然还有这招!真是绝了:


#include <stdio.h>

//////////////////////////////////////////////////////////////////////////
// 被回调的类
class CCallBack
{
public:
    // 测试的被回调的函数
    void TestFunc(int a)
    {
        printf("%d\n", a);
    }
};

// 声明被回调函数类型
typedef void(CCallBack::*TESTFUNC)(int);

//////////////////////////////////////////////////////////////////////////
// 调用回调的类
class CMyCall
{
    CCallBack*    m_pCallBack;    // 首先要有回调类对象指针
    TESTFUNC    m_CallFunc;        // 还要回调函数的指针
    // 二者缺一不可

public:
    CMyCall()
    {
        // 初始化一下,不要也行
        m_pCallBack = 0;
        m_CallFunc = 0;
    }

    // 设置回调函数的指针
    void SetFuncPtr(TESTFUNC f)
    {
        m_CallFunc = f;
    }

    // 调用它!
    void Call()
    {
        // 以下这种调用的格式是很重要的,是本代码的核心部分
        // 大家得记清楚了
        (m_pCallBack->*m_CallFunc)(18);
    }
};

//////////////////////////////////////////////////////////////////////////
// 用于测试的类
class RUN
{
public:
    RUN()
    {
        CMyCall my;
        my.SetFuncPtr(CCallBack::TestFunc);        // 看,就像这样把TestFunc的指针传给它
        my.Call();                                // Call It!
    }
};

void main()
{
    RUN run;
}
5 回复
#2
无缘今生2008-08-24 19:22
头都大了

虽然看得不是太懂,但还是佩服楼主的探索精神!
#3
yuki2008-08-24 23:29
使用静态成员函数就能实现回调了,LZ有兴趣做一个Thread的封装就会明白了~
#4
flyue2008-08-25 14:06
由于程序需要,不能做成静态函数。

2楼的,就这一点点代码,你还看的头大?
哎,可惜了我的游戏哦,要是开源一下,真不知道有多少人看呢
#5
suyilin682008-08-25 15:35
佩服。。
#6
中学者2008-08-28 17:13
喜欢这种全OO的感觉
1