函数指针作为类的成员

时间:2013-08-14 10:45:03

标签: c++ function class pointers

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

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

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

2 个答案:

答案 0 :(得分:5)

成员函数指针(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)并且仍在工作,只要在代理程序中使用正确的参数进行调用。

答案 1 :(得分:0)

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

相关问题