在多线程程序中,无论我们使用AfxBeginThread ,CreateThread,_beginthread构造线程函数,因为线程函数只能是全局函数或静态函数,下面拿静态函数来举例说明,静态函数中可以直接访问静态成员,但是访问类的非静态函数或成员变量就必须做一个适配器,代码如下:
class CStaticThread
{
public:
static int ThreadFunc(LPVOID pParam);/
protected:
int ThreadFuncKernal();
}
void CStaticThread::Func()
{
AfxBeginThread(TreadFunc, this);
}
int CStaticThread::ThreadFunc(LPVOID pParam)
{
CStaticThread*pObj = (CStaticThread*)pParam;
return pObj->ThreadFuncKernal();
}
// Thread function kernal
int CStaticThread::ThreadFuncKernal()
{
while(1)
{
// my thread
// to control class non-static member
}
return 0;
}
上面这个例子 是我们实际应用中这么操作的,下面讲讲static成员函数和非static成员的区别。
static成员函数和成员变量的主要作用是针对类的,对所有的对象共享。声明为static的类成员或者成员函数便能在类的范围内共同享,我们把这样的成员称做静态成员和静态成员函数。
静态成员的初始化应该在主函数调用之前,并且不能在类的声明中出现,静态成员的使用应该是类名称加域区分符加成员名称的,虽然我们仍然可以使用对象名加点操作符号加成员名称的方式使用,但是不推荐的,静态类成员的特性就是属于类而不专属于某一个对象。静态成员函数与普通成员函数的差别就在于缺少this指针。
静态成员函数的作用:
主要有两个作用:
1、管理静态数据成员;
2、提供类范围的功能,即不需要对象来实现的功能。
由于一个类的静态成员函数只有一个拷贝,因此它访问对象的数据何函数使受到了限制。静态成员函数可以直接访问该类的静态数据成员。而访问非静态数据成员,必须通过参数传递方式得到对象名,然后通过对象名来访问。上面举得线程的例子就是通过参数传递得到对象名,然后通过对象来访问,这样在线程中,不但可以公有成员,也可以访问私有成员和成员函数;
使用静态函数注意点:
1)静态成员可以被继承,基类和派生类共享该静态成员;
2)构造函数不能申明成静态的;
因为构造函数是对每个对象进行初始化的,而静态函数是在类中的对象共享的,所以矛盾
3)虚函数不能是静态函数;
为什么虚函数必须是非静态成员函数
如果定义为虚函数,那么它就是动态绑定的,也就是在派生类中可以被覆盖的,这与静态成员函数的定义本身就是相矛盾的。