一、静态线程函数与类的非静态函数
今天写程序要用到一个计时器,然后需要创建一个新的线程,这个线程是CtestDLG的一个成员函数,必须定义为静态的.但是这个时候就不能去访问非静态成员变量了,这里找到一个很好的解决办法:
先上代码:
1.线程函数的定义:
private: int Count_time; CTime C_time; bool GetQuestion(); int mark;//考试分值,五个题目,一个20分,满分100 int QS[5];//随机题库序号 int count2;//题库总数 int count_Q;//当前输出的题目数量 static DWORD WINAPI Fun_Time(LPVOID lpParameter); };
我们可以看到这个是一个类的成员函数
2.创建线程
void CTESTDlg::ONTIME() { HANDLE pThread_time = NULL; pThread_time = CreateThread(NULL,0,Fun_Time,this,0,NULL); }
这个是在一个消息函数中创建的.第四个参数传递的是一个this指针,指向当前的窗口类(这里很重要)
2.具体实现
DWORD WINAPI CTESTDlg::Fun_Time(LPVOID lpParameter) { CTESTDlg* temp = (CTESTDlg*)lpParameter; temp->Count_time++; while(1) { AfxMessageBox("s"); } return 0; }
这里我们可以看到,窗口句柄传递过来,然后通过强制类型转换,将它复制给一个新的临时变量,然后用这个临时的指针就可以去访问类的成员了.很好的一个解决办法!!
思想的总结如下:
创建线程时,线程函数如果要设置成类的成员函数,则必须是静态成员函数,在此函数种不能使用非静态成员变量,如果要使用非静态成员变量,则一种比较适合线程的方法是:建立线程的时候把this作为CreateThread的一个参数(即第4个参数,就是那个LPVOID型的),然后线程里就对应pParam,例如:
static UINT ThreadProc(LPVOID pParam)
{
Your_Class *p=(Your_Class *)pParam;
//然后用p间接使用成员变量。
}
线程函数是回调函数,因此它必须是静态成员函数或者是类外部声明的全局函数。
https://www.cnblogs.com/color-my-life/p/3219669.html
二、类的静态函数调用非静态函数
this 指针不能在静态成员函数中使用,因为静态成员函数不是通过它们所属类的任何实例调用的。而且,静态成员函数除非指定该成员属于哪个实例,否则不能访问其类的实例成员。
示例:来看以下类定义语句:
class StatAccess
{
private:
int x;
public:
static void output()
{
cout << x; //对非静态成员的不正确访问
}
StatAccess(int x) { this->x = x; }
};
在语句 cout<<x 中试图访问 x 是不正确的,因为它等于隐式使用 this 指针,而这是静态函数 output 所不具有的。相反,在以下修改过的同一个类的示例中,静态成员函数 print 正确地访问了非静态成员 x,因为它使用了传递给它的类对象的名称作为形参来限定它。
class StatAccess
{
private:
int x;
public:
static void print(StatAccess a)
{
cout << a.x;
}
StatAccess(int x) { this->x = x; }
};
静态成员函数的一个优点是可以在任何类的实例被创建之前调用它们,这使得它们可以用来执行复杂的初始化任务,这些任务必须在创建类的对象之前完成。
三、类的静态函数的基础知识
静态函数只在头文件声明时使用static,定义时不使用static。
对象与对象之间的成员变量是相互独立的.要想共用数据,则需要使用静态成员或静态方法;
只要在类中声明静态成员变量,即使不定义对象,也可以为静态成员变量分配空间,进而可以使用静态成员变量.(因为静态成员变量在对象创建之前就已经被分配了内存空间)
静态成员变量虽然在类中,但它并不是随对象的建立而分配空间的,也不是随对象的撤销而释放(一般的成员在对象建立时会分配空间,在对象撤销时会释放).静态成员变量是在程序编译时分配空间,而在程序结束时释放空间.
初始化静态成员变量要在类的外面进行.初始化的格式如下:数据类型 类名::静态成员变量名 = 初值;
不能用参数初始化表,对静态成员变量进行初始化.
即可以通过类名来对静态成员变量进行引用,也可以通过对象名来对静态成员变量进行引用.
普通成员函数和静态成员函数的区别是:普通成员函数在参数传递时编译器会隐藏地传递一个this指针.通过this指针来确定调用类产生的哪个对象;但是静态成员函数没有this指针,不知道应该访问哪个对象中的数据,所以在程序中不可以用静态成员函数访问类中的普通变量.。