如果我有会员功能。 。
MyClass::MyFunction()
{
while(1)
{
//blah blah blah
}
}
。 。 。我尝试创建这个函数的线程。 。
CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)MyFunction, NULL, 0, NULL);
。 。 。我总是得到一个错误,说(LPTREAD_START_ROUTINE)MyFunction是一个无效的类型转换,我无法创建非静态成员函数的线程。
我无法使我的函数静态,因为我多次使用 this 指针需要非静态成员函数来执行此操作。
有没有简单的方法来创建非静态成员函数的线程?
(我在Visual Studio 2010,C ++,MFC工作)
答案 0 :(得分:4)
除了“start()”函数之外,您应该对所有这些信息进行私有化。您将拥有类的私有静态成员函数作为操作系统的线程启动的目标,在“start()”中传递线程启动方法对象的“this”指针,将其强制转换为您的对象类型静态函数,然后在对象本身上调用您的私有主线程方法。由于静态函数是类的成员,因此它可以使用私有函数,而如果不是,则它不能(不是朋友)。我没有编译/测试这个,但想法是:
class MyObj {
private:
void thread() {
// this-> is valid here
}
static DWORD static_entry(LPVOID* param) {
MyObj *myObj = (MyObj*)parm;
myObj->thread();
return 0;
}
public:
void start() {
CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)static_entry, this, 0, NULL);
}
};
警告语:在线程运行时不要销毁对象!您可能必须与互斥锁同步或确保线程在对象销毁时加入。如果start()的调用者不再管理对象,你也可以在thread()的末尾执行“delete this”或者在static_entry结束时删除myObj。
答案 1 :(得分:2)
没有类实例就无法调用C ++成员函数。 以下代码是我的建议之一;
MyClass * instance = ...; // valid instance.
CreateThread(NULL, 0, StartRoutine, instance, 0, NULL);
DWORD WINAPI StartRoutine(LPVOID ptr) {
static_cast<MyClass*>(ptr)->MyFunction();
}
另一个建议是使用static
关键字声明成员函数;
class MyClass {
...
static DWORD WINAPI MyFunction();
...
}
在第二个代码中,MyFunction
无法访问类(非static
)成员变量。
答案 2 :(得分:2)
创建静态函数
static DWORD myFunctionCaller(LPVOID* param)
{
MyClass* myClass = static_cast<MyClass*>(param);
myClass->MyFunction();
}
CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)myFunctionCaller, this, 0, NULL);
缺点是您获得了一些浮动静态函数,但您可以轻松限制范围,这样可以防止您创建太多线程