关于函数指针和事件的问题!

yyfhz 2003-03-07 01:21:10
有一个类CTest,当中有一个方法exec(),在执行该方法时可能要做一些别的事情,比方说打印结果,或者是在窗口上显示计算结果,也可能会是别的事。我不想为每一种要做的事情都写一个继承类,而在写CTest的时候又实在不知道要做的事情,所以打算用一个函数指针来做。
CTest ...
{
..
public:
{
void (* OnExec)(int result) ;
int exec() {
//把计算结果放入变量 nResult
if ( OnExec!=NULL)
(*OnExec)(nResult) ;
}
}
}

//在主程序里写上
void ShowResult(int result)
{
//显示result...
}

void PrintResult(int result)
{
//打印result...
}

...
{
CTest newTest ;
newTest.OnExec= ShowResult ;
newTest.exec() ; //计算并显示结果
newTest.OnExec= PrintResult ;
newTest.exec() ; //计算并打印结果
}

运行一切正常,
但是如果ShowResult是某个类里的方法的时候就不可行了,好象不能直接访问VC的类里面的方法的地址。有谁知道应该怎么做?本人感激不尽!!!
...全文
48 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyfhz 2003-03-14
  • 打赏
  • 举报
回复
没有更好的方法了吗?
yyfhz 2003-03-10
  • 打赏
  • 举报
回复
总算解决了。我把newTest作为一个参数传入OnExec事件中,然后在newTest的ShowResult(int result, CObject* SELF)中进行转换
{
CResult* self= (CResult*) SELF ;
然后在函数中所有使用this指针的地方全部用self来替换它。
}

不过这样的函数体看起来很奇怪,
谁有更好的方法,请告之。
yyfhz 2003-03-09
  • 打赏
  • 举报
回复
可是,在建立这个类的时候,我还不知道可能有多少种处理方法啊。
yndfcd 2003-03-08
  • 打赏
  • 举报
回复
错了,上面好像也不能解决,必需再加一个中间层:
class CMyObject:public CObject
{
public:
virtual void Function1(int);
virtual void Function2(int);
virtual void Function3(int);
...
}
其中Function1.2.3。。。为所有可能出现的函数。
然后将CResult 从CMyObject来派生。并把上面的CObject改为CMyObject
yndfcd 2003-03-08
  • 打赏
  • 举报
回复
解决的方法是不要声明OnExec为一个变量,将它声明为一个函数
CTest
{
public:
void OnExec(void (CObject::* pfnTodo)(int),int pfnPrama);
}
void CTest::OnExec(void (CObject::* pfnTodo)(int), int pfnPrama)
{
pfnTodo(pfnPrama);
}
yyfhz 2003-03-08
  • 打赏
  • 举报
回复
后来我采用了这样的方法,
typedef void (CObject::* ExecEvent)(int result) ;
把CTest的指针改为 ExecEvent OnExec;
主程序改为newTest.OnExec=(ExecEvent)res->ShowResult ;
编译可以通过,调试时也进入了函数体,可是... 在函数里没法访问m_FormatStr ;查看this指针的内容时居然发现它是个CTest类型的指针! 书上讲当调用对象的方法的时候,它隐含的重新设置this指针.大概由于调用指针OnExec时不知道它是某个对象中的方法,所以this指针仍然指向newTest对象. 谁能告诉我解决的办法?
yyfhz 2003-03-07
  • 打赏
  • 举报
回复
多谢 !
不过,象这样的情况应该怎么处理呢?
class CResult...
{
public
m_FormatStr: CString ;
//使用用户给出的格式显示结果,由于使用了内部变量,是不是还能使用static关键字呢?
void ShowResult(int result)
{
CString res ;
res.format(m_FormatStr, result) ;
//显示res.
}
}

...
CResult *res;
CTest newTest ;
res= new CResult ;
res.m_FormatStr="format1: %d" ;
newTest.OnExec= res->ShowResult ;//已经创建了实例,为什么不能直接访问里面的ShowResult的地址呢?
newTest.exec() ;
res.m_FormatStr="format2: %d" ;
newTest.exec() ;

编译时报的错误是:can not convert from "void(__thiscall CResult::*)(int)" to "void(__cdecl*)(int)".
如果CTest中的指针改为
void (CTest::* OnExec)(int result) ;
报的错误就变成了 can not convert from "void(__thiscall CResult::*)(int)" to "void(__thiscall CTest*)(int)".
应该怎么办呢?
vivianm 2003-03-07
  • 打赏
  • 举报
回复
bhw98(bhw98)的第二种方法是什么意思呢?不懂。为什么就可以呢?
Roxxette 2003-03-07
  • 打赏
  • 举报
回复
GZ
bhw98 2003-03-07
  • 打赏
  • 举报
回复
类里面的方法,需要声明为static

或 void (* OnExec)(int result); --> void (CTest::* OnExec)(int result);
yndfcd 2003-03-07
  • 打赏
  • 举报
回复
如果是类里的函数要声明为静态函数。不然的话,如果该类的实例还没有创建,去哪里找函数的地址。

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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