C ++类:指向非静态函数的指针

时间:2011-09-21 11:53:23

标签: c++ multithreading class visual-c++ function-pointers

这是我的last question。我尝试改进我的类Thread。 构造函数接收指向函数的指针,该函数必须在新线程中运行。

class Thread { 
    public:
     Thread(void (*p)()) {
        pf=p;
      }
     ~Thread () {}
    void StartThread() {
     hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, NULL, 0, &threadID); 
    }
    private: 
     void (*pf)();
     HANDLE hThread; 
     unsigned threadID;
     static unsigned WINAPI ThreadProc(LPVOID lpParam) {
      (*pf)(); //error C2597 illegal reference to non-static member
      return 0; 
     }
    }; 

在ThreadProc中我需要调用TimerFunc。

void TimerFunc () {
    i++;
}

此类的使用示例:

Thread *timer; 
timer = new Thread(TimerFunc);  
timer->StartThread();

所以它不起作用。 如果这堂课愚蠢,请有人告诉我。 将指针发送到位于类外的func可能是一个坏主意? 谢谢。

非常感谢您的建议! 现在它有效!

class Thread { 
public:
    Thread(void (*p)()) {
        gg.pf=p;
    }
    ~Thread ();
    void StartThread() {
     hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, this, 0, &threadID); 
    }
private: 
    struct mm {
        Thread *pThread; 
        void (*pf)();
    } gg;
    HANDLE hThread; 
    unsigned threadID; 
    static unsigned WINAPI ThreadProc(LPVOID lpParam) {
        mm hh; 
        hh.pThread=static_cast<Thread*> (lpParam);
        hh.pf=hh.pThread->gg.pf;
        hh.pf();
        return 0; 
    }
}; 
你怎么看?这是正确的选择吗?

3 个答案:

答案 0 :(得分:3)

正如outhers指出的那样,问题是静态方法无法访问非静态成员。执行此类操作的常用方法是将对象作为参数传递给线程启动例程,例如:

class Thread { 
public:
    Thread(void (*p)()) {
        pf=p;
    }
    ~Thread () {}
    void StartThread() {
        // Pass this as argument to ThreadProc
        hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, this, 0, &threadID); 
    }
private: 
    void (*pf)();
    HANDLE hThread; 
    unsigned threadID;
    static unsigned WINAPI ThreadProc(LPVOID lpParam) {
        // Get the passed Thread object
        Thread *pThread = static_cast<Thread*> (lpParam);
        pThread->pf();
        return 0; 
    }
}; 

答案 1 :(得分:2)

问题是ThreadProc被定义为静态,这意味着它没有绑定到对象。然后,您尝试使用非静态的类成员,并且必须绑定到对象。

克服这个问题的典型方法是通过创建函数接受的void *指针将结构传递给线程。这个结构应该包含你需要的参数。在其中的某个地方,您应该有一个指向您尝试将对象绑定到的类的指针。然后,通过这个指针参考pf。

答案 2 :(得分:1)

您的ThreadProc成员函数是静态成员函数。因此,它无权访问任何非静态成员或成员函数,包括pf。我明白为什么你决定让TreadProc成为静态成员函数 - 因为那样你就可以将它作为普通函数指针传递给_beginthreadex

嗯,如你所见,这种方法存在问题。解决这个问题并非易事。您可以查看boost thread实施情况,看看他们是如何做到的。