作为类成员的函数指针

Function pointer as a member of a class

本文关键字:函数 指针 成员      更新时间:2023-10-16

C++中的函数指针方面,类函数和全局函数有什么区别?我问,因为如果 Windows CreateThread 方法是类成员,则似乎不接受线程代码进入的函数。

当它是全局方法时,我可以将函数(线程代码进入(传递给 CreateThread 消息,但是一旦我使其成为类的成员,我就会收到错误"类型 [方法布局] 的参数与类型 LPTHREAD_START_ROUTINE 的参数不兼容"。类名::*现在在中间;这会影响它吗?

解决这个问题的方法是什么?

成员函数指针(DWORD(WINAPI Foo::*)(LPVOID)(与函数指针(DWORD(WINAPI *)(LPVOID)(的类型不同。成员函数具有隐藏的this参数,从而导致签名不匹配。

最简单的方法是使用 C++11 的 <thread> 标头:

struct Foo {
    void threadProc() {}
};
int main() {
    Foo foo;
    std::thread t{&Foo::threadProc, foo, /*other arguments to threadProc*/};
    t.join();
}

如果必须求助于 CreateThread ,请使用 void * 参数传递实例:

struct Foo {
    DWORD threadProc() {...}
};
extern "C" DWORD WINAPI proxyThreadProc(LPVOID userData) {
    auto foo = static_cast<Foo *>(userData);
    if (foo) {foo->threadProc();}
}
int main() {
    Foo foo;
    CreateThread(..., proxyThreadProc, &foo, ...);
}

你的类中的那个现在几乎可以是你想要的任何东西(比如std::function(,只要它在代理过程中使用正确的参数调用,它就可以工作。

是的,正如@chris所说,有一个隐藏的指针,它将通过参数的末尾连接。 当线程执行此操作时,它不知道与最后一个参数位置的指针匹配,那么它在完成后无法恢复此函数的堆,因此禁止使用类的非静态成员函数来驱动除全局函数或静态之外的线程函数类的成员函数。