2010-03-08 429 views
15

我試圖在類中聲明一個回調函數,然後在某處我讀取的函數需要是靜態的,但它沒有解釋爲什麼?爲什麼回調函數在類中聲明時需要是靜態的

#include <iostream> 
using std::cout; 
using std::endl; 

class Test 
{ 
public: 
    Test() {} 

    void my_func(void (*f)()) 
    { 
     cout << "In My Function" << endl; 
     f(); //Invoke callback function 
    } 

    static void callback_func() 
    {cout << "In Callback function" << endl;} 
}; 

int main() 
{ 
    Test Obj; 
    Obj.my_func(Obj.callback_func); 
} 

回答

20

成員函數是一個需要調用類實例的函數。 如果不提供要調用的實例,則不能調用成員函數。這使得有時難以使用。

靜態函數幾乎就像一個全局函數:它不需要調用一個類實例。所以你只需要獲得指向該函數的指針就可以調用它。

看看std :: function(或者std :: tr1 :: function或者boost :: function,如果你的編譯器還沒有提供的話),它對你的情況很有用,因爲它允許你使用任何是可調用的(提供()語法或運算符)作爲回調,包括可調用對象和成員函數(請參閱本例的std :: bind或boost :: bind)。

8

回調需要是靜態的,因此它們沒有隱含的this參數作爲其函數簽名中的第一個參數。

0

如果使用函數指針,那麼在調用函數時,運行時環境無法將引用傳遞給實例。但是你可以使用std :: mem_fun <>來使用函子和成員方法。

2

它需要是靜態的,以便函數簽名匹配。當調用成員函數時,調用中會包含一個隱藏參數(即「this」指針)。在靜態成員函數中,這個指針不作爲參數傳遞。

2

Marshal Cline給你完整的答案here 。整個部分包含你需要知道的一切。

總而言之,它可以解釋你需要一個靜態成員,因爲不需要this指針(與普通成員方法不同)。但是它也涵蓋了使用靜態對所有編譯器來說可能不夠,因爲C和C++之間的C++調用約定可能不同。

所以建議使用extern "C"非成員函數。

+1

您的鏈接已損壞。另外,最好發佈實際答案而不是鏈接。 – 2015-08-21 03:52:06

+0

@BenH感謝您的單挑。改進的答案和固定鏈接。 – daramarak 2015-08-21 06:57:18

+0

加上一個鏈接(非常有幫助和易於理解的解釋) – 2016-12-29 10:37:21

相關問題