我真是难…现在有一个类,类里面要使用多线程完成对机器的链接状态访问。
那么问题来了:
为了能让线程函数参入到类中的数据处理,这个线程函数要么作为类的成员函数,要么设为友元函数。
如果单纯的作为类的成员函数,那么这个又存在一个问题,就是因为成员函数隐含的this指针会导致线程函数不满足AfxBeginThread以及_beingthreadex等函数的参数要求。在这里卡住了。
函数声明都没问题,但是就差在this指针上。
所以只要除去this指针就能实现要求。
我们知道C++中,静态成员函数是不存在this指针的。
接下来就很简单了,函数前面添加一个static就OK了~
但是另外需要注意的是,因为静态成员函数不允许访问类中的非静态成员变量(因为没有this指针),所以在线程函数中,在参数中传入this指针。
有点绕弯了,是吧?
其实this指针就是当前对象的首地址,可以通过类型转换来使用哦。
当然,如果你觉得有点烦,可以使用友元函数的。这种方法能保证更好地封装性。
使用友元函数的方法:
多线程程序的线程函数需要使用类的成员变量和成员函数时,通常通过定义线程函数为类的友元函数,然后才能像类自己的成员函数一样访问其成员变量和成员函数。这种方式非常的方便尤其相对于通过定义静态全局线程函数和定义类的静态成员线程函数的方法有很大的优点,它能够访问类所有的成员变量和成员函数。
这里有几点需要注意的是:
1.定义线程函数时,除了需要在类的里边声明为友元函数,也要在该声明头文件顶部再次声明该线程函数,同时具体地定义该线程函数时也要将其放置在定义类文件的顶部,也就是说除了将其定义为类的友元函数这一点有些特别之外实际上也是将其作为一个全局函数来对待的。
2.在使用MFC线程类的AfxBeginThread创建线程函数调用并非类的线程函数时,需要对其进行(AFX_THREADPROC)类型强制转换,不然会出现错误如下:
error C2665: ‘AfxBeginThread’ : none of the 2 overloads can convert parameter 1 from type ‘void (__cdecl *)(void *)’。这一点非常重要。
3.
4.
下面给出一个示范例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
ClassADlg.h //类头文件 void threadProc(LPVOID lpv); /////////////////////////// class ClassADlg: public CDialog { Public: friend void threadProc(LPVOID lpv); } ClassADlg.cpp //类实现文件 Include” ClassADlg.h” //////////////////////// void threadProc(LPVOID lpv) { ClassADlg * pMain = (ClassADlg *) lpv; //强制转换获得传入的类对象指针 int a= pMain->ax; //获得传入的类对象的成员变量 pMain->add(a); //调用传入的类对象的成员函数 } ///////////////////////////////////////////// Void test(void) { CWinThread* cWth1=AfxBeginThread((AFX_THREADPROC) threadProc,(LPVOID)this); //创建线程 } |