说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

如何将一个类的成员函数(非static)作为参数传递?

编辑:说三道四文库 发布时间:2018-02-18 09:07
HTML文档下载 WORD文档下载 PDF文档下载
函数指针对类的成员函数不起作用……

背景是这样的,我要使用pthread_create创建一个新的线程。

pthread_create()的第3个参数是个函数指针,如何能让这个参数指向的是一个类的成员函数(非static)?
^^^^^
不懂,帮顶
类成员函数不能用作回调,好像解决办法是用Thunk
http://www.examda.com/ncre2/cpp/jichu/20090708/075710951.html
额 用一个静态成员函数,然后传递对象去调用另外一个非静态成员函数即可。
引用 4 楼 pengzhixi 的回复:
额 用一个静态成员函数,然后传递对象去调用另外一个非静态成员函数即可。

这个方法应该可以
引用 4 楼 pengzhixi 的回复:
额 用一个静态成员函数,然后传递对象去调用另外一个非静态成员函数即可。

++
如果想直接传成员函数并使用,那就复杂了。类的成员函数隐含了个this指针参数
引用 3 楼 bdmh 的回复:
类成员函数不能用作回调,好像解决办法是用Thunk
http://www.examda.com/ncre2/cpp/jichu/20090708/075710951.html


++++1
首先楼主应该了解下 函数指针 与 类的成员函数 有什么关系

就是 什么样的函数可以做为函数指针

因为函数指针是在编译时候确认地址的。所以函数只能是“全局函数和静态函数”。

这就是为什么你说的 类的成员函数不能当作函数指针的原因所在。

上面说的俩种方式呢,我觉得thunk做为了解不错。而第二种其实用到的还是一个静态函数。
引用 4 楼 pengzhixi 的回复:
额 用一个静态成员函数,然后传递对象去调用另外一个非静态成员函数即可。

我理解你的意思,是不是说this将成为pthread_call的第4个参数?
那么对于linux上实现一个定时器模块来说:

1、这里有一个定时器类,叫做SYSZUXTimer,其有一个方法,叫做startTimer(),调用这个方法,可以启动一个定时器。startTimer的函数如下实现:
void SYSZUXTimer::startTimer()
{
pthread_create(&timer, NULL, threadCall, this);
}

那么这里,threadCall一定是个静态函数了。

2、依据第4个参数this,将对象传递了过去,threadCall的实现如下:
void SYSZUXTimer::threadCall(void *p) //static
    {
        (static_cast<SYSZUXTimer*>(p))->timeout();
    }

其中,timeout()为SYSZUXTimer的非static成员函数。实现如下:
void SYSZUXTimer::timeout()
{
    while (1){
        val->tv_sec = syszux_s;//val是timeval结构体,syszux_s是秒数
        val->tv_usec = syszux_ms;
        select(0, NULL, NULL, NULL, val);//变量简单,我就不解释了。
    }
}

正是在timeout()里实现了新线程中的定时循环执行。

3、现在,SYSZUXTimer成为了一个定时器模块,要在其他类中(比如类 A、B、C,各自互不相关)使用。现在要定时执行A、B、C各自的方法send(),这些方法互不相关。

问题是,如何使timeout的定时执行也能够使send()定时执行?也就是针对A、B、C,每个类都通过SYSZUXTimer实现了各自的定时(3个线程)。

备注:我之前是通过使A、B、C继承自SYSZUXTimer,然后通过虚函数实现A、B、C各自的定时send()。但我不想使A、B、C继承SYSZUXTimer。
使用类似单子模式的获得指针方法,然后用那个静态方法作为函数指针。。
引用 9 楼 gemfield 的回复:
引用 4 楼 pengzhixi 的回复:

额 用一个静态成员函数,然后传递对象去调用另外一个非静态成员函数即可。

我理解你的意思,是不是说this将成为pthread_call的第4个参数?

也可以,但是你可以直接传参给静态成员函数。
stl::mem_fun
就用静态成员函数吧。。。不要搞的那么复杂。
引用 10 楼 gemfield 的回复:
那么对于linux上实现一个定时器模块来说:

1、这里有一个定时器类,叫做SYSZUXTimer,其有一个方法,叫做startTimer(),调用这个方法,可以启动一个定时器。startTimer的函数如下实现:
C/C++ code
void SYSZUXTimer::startTimer()
{
    pthread_create(&amp;timer, NULL, thread……

++++1
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘