C++回调函数

我们经常会把一些耗时的操作放到线程中去执行,当任务执行完毕后就需要通知主线程,通知的方式有很多,在windows平台上可以使用消息机制,如果不想依赖平台API,让代码具有良好移植性,使用回调函数也是一种方法。

(1)定义函数指针类型

typedef void(*pResult)(int);

(2)在类的内部定义一个函数指针对象

private:

  pResult m_ResultEvent;

(3)添加一个函数用来指定回调函数

void setResultEvent(pResult event)

{

  m_ResultEvent=event;

}

(4)在线程任务完成后回调函数通知主线程

void run()

{

     //do something

  if(m_ResultEvent)

    m_ResultEvent(1);

}

(5)在主线程中定义回调处理函数

需要注意的是函数只能定义为静态函数,只有全局函数或静态函数才能作为函数指针传递。

class MainObject

{

public:

  MainObject();

private:

       ThreadObject m_Thread;

  int m_Status;

  static void doResult(int status);

}

MainObject::MainObject()

{

  m_Thread.setResultEvent(doResult);
}

这样回调的功能就基本实现了。但是如果回调函数只能传静态函数,那么在回调函数中如何与实际的对象联系呢。

我们可以把对象作为回调函数的一个参数,这样通过调用这个参数就可以实现对此对象的访问了。可以将上面的回调函数做一下改造。

typedef void(*pResult)(const void *p,int);

修改线程设置函数,传入对象指针,并保存

private:

void * m_Object;

void setResultEvent(void *p,pResult event)

{

  m_ResultEvent=event;

  m_Object=p;

}

在调用的时候将对象this指针传入:

MainObject::MainObject()

{

  m_Thread.setResultEvent(this,doResult);
}

//将对象指针作为参数传入回调函数中

void run()

{

     //do something

  if(m_ResultEvent)

    m_ResultEvent(m_Object,1);

}

//在处理函数中将void*指针强转为需要的对象类型:

void MainObject::doResult(const void *p,int status)

{

  MainObject *obj=(MainObject *)p;

  obj->m_Status=status;

}

以上就是C++中对象回调通知的方式,回调函数主要使用了函数指针的概念,实际在C语言中就已存在,C++继承了这种机制,但是由于函数只能传入静态的或全局的,所以封装性并不好,类型强制转换也显得繁琐。在C++中有新的机制可以实现相似的功能,就是利用std::function和std::bind来实现。

猜你喜欢

转载自www.cnblogs.com/WushiShengFei/p/9232756.html