成员函数做为线程函数

一般来说,C++的类成员函数不能作为线程函数。这是因为在类中定义的成员函数,编译器会给其加上this指针。 

[cpp]  view plain copy
  1. #include "windows.h"  
  2. #include <process.h>  
  3.   
  4. class ExampleTask  
  5. {  
  6.  public:  
  7.   void taskmain(LPVOID param);  
  8.   void StartTask();  
  9. };  
  10. void ExampleTask::taskmain(LPVOID param){}  
  11. void ExampleTask::StartTask()  
  12. {  
  13.  _beginthread(taskmain,0,NULL);  
  14. }  
  15.   
  16. int main(int argc, char* argv[])  
  17. {  
  18.  ExampleTask realTimeTask;  
  19.  realTimeTask.StartTask();  
  20.  return 0;  
  21. }  

程序编译时出现如下错误:
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


再看下列程序:

[cpp]  view plain copy
  1. #include "windows.h"  
  2. #include <process.h>  
  3.   
  4. class ExampleTask  
  5. {  
  6.  public:  
  7.   void taskmain(LPVOID param);  
  8. };  
  9. void ExampleTask::taskmain(LPVOID param){}  
  10.   
  11. int main(int argc, char* argv[])  
  12. {  
  13.  ExampleTask realTimeTask;  
  14.  _beginthread(ExampleTask::taskmain,0,NULL);  
  15.  return 0;  
  16. }  

程序编译时会出错:
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指针;
我们将上述二个程序改变为:

[c-sharp]  view plain copy
  1. #include "windows.h"  
  2. #include <process.h>  
  3.   
  4. class ExampleTask  
  5. {  
  6.  public:  
  7.   void static taskmain(LPVOID param);  
  8.   void StartTask();  
  9. };  
  10. void ExampleTask::taskmain(LPVOID param)  
  11. {}  
  12. void ExampleTask::StartTask()  
  13. {  
  14.  _beginthread(taskmain,0,NULL);  
  15. }  
  16.   
  17. int main(int argc, char* argv[])  
  18. {  
  19.  ExampleTask realTimeTask;  
  20.  realTimeTask.StartTask();  
  21.  return 0;  
  22. }  

[c-sharp]  view plain copy
  1. #include "windows.h"  
  2. #include <process.h>  
  3.   
  4. class ExampleTask  
  5. {  
  6.  public:  
  7.   void static taskmain(LPVOID param);  
  8. };  
  9. void ExampleTask::taskmain(LPVOID param){}  
  10.   
  11. int main(int argc, char* argv[])  
  12. {  
  13.  _beginthread(ExampleTask::taskmain,0,NULL);  
  14.  return 0;  
  15. }  

均编译通过。
将成员函数声明为静态虽然可以解决作为线程函数的问题,但是它带来了新的问题,那就是static成员函数只能访问static成员。解决此问题的一种途径是可以在调用类静态成员函数(线程函数)时将this指针作为参数传入,并在改线程函数中用强制类型转换将this转换成指向该类的指针,通过该指针访问非静态成员。


(2)不定义类成员函数为线程函数,而将线程函数定义为类的友元函数。这样,线程函数也可以有类成员函数同等的权限;
我们将程序修改为:

[cpp]  view plain copy
  1. #include “windows.h"  
  2. #include <process.h>  
  3.   
  4. class ExampleTask  
  5. {  
  6.  public:  
  7.   friend void taskmain(LPVOID param);  
  8.   void StartTask();  
  9. };  
  10. void taskmain(LPVOID param)  
  11. {  
  12.  ExampleTask * pTaskMain = (ExampleTask *) param;  
  13.  //通过pTaskMain指针引用  
  14. }  
  15. void ExampleTask::StartTask()  
  16. {  
  17.  _beginthread(taskmain,0,this);  
  18. }  
  19.   
  20. int main(int argc, char* argv[])  
  21. {  
  22.  ExampleTask realTimeTask;  
  23.  realTimeTask.StartTask();  
  24.  return 0;  
  25. }  


(3)可以对非静态成员函数实现回调,并访问非静态成员,此法涉及到一些高级技巧,在此不再详述

你可能感兴趣的:(c,null,include,编译器)