2017-03-02 106 views
0

此代碼編譯(使用g ++(GCC)6.3.1)並顯示爲「工作」。但我非常懷疑它是否構成良好做法將指針指向成員函數作爲指向C函數的指針是一種很好的做法

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 


class ThreadObj 
{ 
    public: 
    void *memberFunction(void*); 
    void startThread(void); 
    static int w; 
}; 

int ThreadObj::w = 13; 

void* ThreadObj::memberFunction(void*) 
{ 
    w = 17; 
    return 0; 
} 

void ThreadObj::startThread(void) 
{ 
    void * (*p)(void *) = *((void * (*)(void *))&ThreadObj::memberFunction); 
    pthread_t tid; 

    if (pthread_create(&tid, 0, p, this) == 0) 
    pthread_detach(tid); 
} 

int main(int argc, char *argv[]) 
{ 
    ThreadObj thr; 
    thr.startThread(); 

    return 0; 
} 

鑄造一個指針指向一個成員函數作爲一個指向C函數並傳遞this作爲數據似乎依賴(TOO MUCH)時的編譯器選擇如何解釋憐憫/編譯此。

這已被覆蓋但尚未明確回答。

這個例子如何被打破?

+5

您此標記爲'C',但目前還沒有這樣的事情在'C'成員函數。 – PaulMcKenzie

+2

由於不同類型的函數的投影指針是未定義的行爲,因此被破壞。 –

+2

任何使用'reinterpret_cast'(或等效C cast)強制轉換的函數指針,除了轉換回原始類型之外,都是未定義的行爲。見'7)'[這裏](http://en.cppreference.com/w/cpp/language/reinterpret_cast#Explanation)。這不是很好的做法,因爲它不允許在C++中使用。你*可以做的是定義一個新的靜態方法,它接受一個指向類實例的指針,並使用指向該方法的函數指針。 –

回答

1

舊的方式(最近語法)去爲:

class ThreadObj 
{ 
public: 
    void memberFunction() { w = 17;} 
    void startThread() { 
     pthread_t tid; 

     if (pthread_create(&tid, 0, &Func, this) == 0) { 
      pthread_detach(tid); 
     } 
    } 
    static void* Func(void* p) { 
     auto* that = static_cast<ThreadObj*>(p); 
     that->memberFunction(); 
     return nullptr; 
    } 
private: 
    int w = 13; 
}; 

但在C++ 11,std::thread有一個更好的界面。

0

不是。這是未定義的行爲。雖然這很可愛。無論它是否有效,都是空氣中的一種。我的猜測是,它通常會。

該代碼的作者利用了這樣的事實,即this通常作爲第一個參數傳遞給成員函數的實現。

0

使用指針指向類的方法非常有用,對我而言,這是一個很好的練習,因爲它允許您實現另一種類型的模式,例如:觸發具有相同方法原型的severas類上的事件。

回答你的問題:這是一個設計問題,它將如何對你的目標有用。

我分享你一個代碼,我在同一類的不同方法上創建了兩個線程,我希望你能幫助你。

https://github.com/jorgemedra/C-11-Threads/blob/master/README.md