指向类成员函数的指针作为另一函数的实参传递

HengStar 2008-05-07 06:40:59

class CGameWindow
{
public:
typedef int (*RenderFun)(void);
void MessageLoop(RenderFun fun);
};

void CGameWindow::MessageLoop(RenderFun fun)
{
fun();
}

class CLobbyClient
{
public:
virtual int Render(void);
};

int CLobbyClient::Render(void)
{
return 1;
}

int (CLobbyClient::*PtrFunc)(void) = &CLobbyClient::Render;

void main()
{
CGameWindow* wnd = new CGameWindow();
CLobbyClient* lobby = new CLobbyClient();

wnd->MessageLoop(lobby->*PtrFunc); // 出错
}

// 错误提示 error C2664: “CGameWindow::MessageLoop” : 不能将参数 1 从“重载函数类型”转换为“CGameWindow::RenderFun”

请问如何能让wnd->MessageLoop(lobby->Render); 这样的语句成功呢?
注意:我不要将Render声明为静态的方法和借助全局函数的调用方法,有别的好的方法不用做大的更改的方法能实现吗?望高人给予回答并解释,谢谢~
...全文
110 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
gaosen_bit 2008-05-07
  • 打赏
  • 举报
回复
[code=c/c++]
// 增加一个函数对象接口的定义,用来封装全局的函数指针
class RenderFun
{
public:
virtual int operator()() { return 0; }
};

// 增加CClient类的前向声明
class CLobbyClient;

class CGameWindow
{
public:
// 这一句删除,因RenderFun已hook至上述函数对象
// typedef int (*RenderFun)(void);
// 参数改为按引用传递
void MessageLoop(RenderFun& fun);
};

void CGameWindow::MessageLoop(RenderFun& fun)
{
fun();
}

class CLobbyClient : public RenderFun
{
public:
virtual int Render(void);
// 实现()算符
int operator()() { return Render(); }
};

int CLobbyClient::Render(void)
{
return 1;
}

// 这一句删除,事实上它声明了一个全局的函数指针,这一点应该不满足楼主的需求吧
// int (CLobbyClient::*PtrFunc)(void) = &CLobbyClient::Render;

void main()
{
CGameWindow* wnd = new CGameWindow();
CLobbyClient* lobby = new CLobbyClient();
// 将下面的函数参数作相应改动
wnd->MessageLoop(*lobby);
}
[/code]
gaosen_bit 2008-05-07
  • 打赏
  • 举报
回复
楼上是正解。
btw,楼主不妨采用static函数。
baihacker 2008-05-07
  • 打赏
  • 举报
回复

//第一种方法是用0看作一个指针,但是对虚函数不起作用
//下面这种方法是用一个类搜索函数调用时需要的信息,在要的时候调用
//lobby->*PtrFunc这种函数对象必须马上进行()操作(见inside the c++ object model)
//而有的编译器支持这种闭包...
#include <iostream>
using namespace std;
class CLobbyClient;
class FUNCTION_CALL
{
typedef int (CLobbyClient::*RenderFun)(void);
CLobbyClient* it;
RenderFun fun;
public:
FUNCTION_CALL(CLobbyClient* _it, RenderFun _fun)
:it(_it), fun(_fun){}
void operator ()(){(it->*fun)();}
};
class CGameWindow
{
public:
void MessageLoop(FUNCTION_CALL fun);
};

void CGameWindow::MessageLoop(FUNCTION_CALL fun)
{
fun();
}

class CLobbyClient
{
public:
int Render(void);
};

int CLobbyClient::Render(void)
{
return 1;
}

int (CLobbyClient::*PtrFunc)(void) = &CLobbyClient::Render;

void main()
{
CGameWindow* wnd = new CGameWindow();
CLobbyClient* lobby = new CLobbyClient();

wnd->MessageLoop(FUNCTION_CALL(lobby, PtrFunc)); // 出错
}
baihacker 2008-05-07
  • 打赏
  • 举报
回复

//不是虚函数可以这样干,我等会儿再给一种方法
#include <iostream>
using namespace std;
class CLobbyClient;
class CGameWindow
{
public:
typedef int (CLobbyClient::*RenderFun)(void);
void MessageLoop(RenderFun fun);
};

void CGameWindow::MessageLoop(RenderFun fun)
{
((CLobbyClient*)0->*fun)();
}

class CLobbyClient
{
public:
int Render(void);
};

int CLobbyClient::Render(void)
{
return 1;
}

int (CLobbyClient::*PtrFunc)(void) = &CLobbyClient::Render;

void main()
{
CGameWindow* wnd = new CGameWindow();
CLobbyClient* lobby = new CLobbyClient();

wnd->MessageLoop(PtrFunc); // 出错
}
zsxcn 2008-05-07
  • 打赏
  • 举报
回复
wnd->MessageLoop(lobby->*PtrFunc)是不是改成
wnd->MessageLoop(lobby->PtrFunc)

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧