一般来说,C++的类成员函数不能作为线程函数。这是因为在类中定义的成员函数,编译器会给其加上this指针。
- #include "windows.h"
- #include <process.h>
- class ExampleTask
- {
- public:
- void taskmain(LPVOID param);
- void StartTask();
- };
- void ExampleTask::taskmain(LPVOID param){}
- void ExampleTask::StartTask()
- {
- _beginthread(taskmain,0,NULL);
- }
- int main(int argc, char* argv[])
- {
- ExampleTask realTimeTask;
- realTimeTask.StartTask();
- return 0;
- }
程序编译时出现如下错误:
error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'
None of the functions with this name in scope match the target type
再看下列程序:
- #include "windows.h"
- #include <process.h>
- class ExampleTask
- {
- public:
- void taskmain(LPVOID param);
- };
- void ExampleTask::taskmain(LPVOID param){}
- int main(int argc, char* argv[])
- {
- ExampleTask realTimeTask;
- _beginthread(ExampleTask::taskmain,0,NULL);
- return 0;
- }
程序编译时会出错:
error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'
None of the functions with this name in scope match the target type
如果一定要以类成员函数作为线程函数,通常有如下解决方案:
(1)将该成员函数声明为static类型,去掉this指针;
我们将上述二个程序改变为:
- #include "windows.h"
- #include <process.h>
- class ExampleTask
- {
- public:
- void static taskmain(LPVOID param);
- void StartTask();
- };
- void ExampleTask::taskmain(LPVOID param)
- {}
- void ExampleTask::StartTask()
- {
- _beginthread(taskmain,0,NULL);
- }
- int main(int argc, char* argv[])
- {
- ExampleTask realTimeTask;
- realTimeTask.StartTask();
- return 0;
- }
和
- #include "windows.h"
- #include <process.h>
- class ExampleTask
- {
- public:
- void static taskmain(LPVOID param);
- };
- void ExampleTask::taskmain(LPVOID param){}
- int main(int argc, char* argv[])
- {
- _beginthread(ExampleTask::taskmain,0,NULL);
- return 0;
- }
均编译通过。
将成员函数声明为静态虽然可以解决作为线程函数的问题,但是它带来了新的问题,那就是static成员函数只能访问static成员。解决此问题的一种途径是可以在调用类静态成员函数(线程函数)时将this指针作为参数传入,并在改线程函数中用强制类型转换将this转换成指向该类的指针,通过该指针访问非静态成员。
(2)不定义类成员函数为线程函数,而将线程函数定义为类的友元函数。这样,线程函数也可以有类成员函数同等的权限;
我们将程序修改为:
- #include “windows.h"
- #include <process.h>
- class ExampleTask
- {
- public:
- friend void taskmain(LPVOID param);
- void StartTask();
- };
- void taskmain(LPVOID param)
- {
- ExampleTask * pTaskMain = (ExampleTask *) param;
- //通过pTaskMain指针引用
- }
- void ExampleTask::StartTask()
- {
- _beginthread(taskmain,0,this);
- }
- int main(int argc, char* argv[])
- {
- ExampleTask realTimeTask;
- realTimeTask.StartTask();
- return 0;
- }
(3)可以对非静态成员函数实现回调,并访问非静态成员,此法涉及到一些高级技巧,在此不再详述