2011-11-26 109 views
2

在我的課,如果我想指向類的成員,指向類的成員

struct S 
{ 
    static int get(); 
    int do_something(); 
    int x; 
}; 

我這樣做,

int (*p)() = S::get; 

不幸的是這並不適用於非靜態成員

int (*p)() = S::do_something; // error 

因爲,靜態成員函數是一個普通的功能,從我來到下方圍繞該帖指出,非靜態成員函數的n也是一個普通的函數,爲什麼它不起作用?這是什麼意思?

(9.2/10)[注:一個非靜態成員函數的類型是普通 功能類型和非靜態數據成員的類型是一個普通的 對象類型。沒有特殊的成員函數類型或數據成員 類型。 ]

+1

這是在這裏回答:http://stackoverflow.com/questions/439540/function-pointer-to-class-member-function-problems –

+1

必須閱讀理解的概念:[指向成員函數](http ://www.parashift.com/c++-faq-lite/pointers-to-members.html) –

回答

2

函數的類型是普通的,而不是函數指針的類型。一個指向非靜態成員函數必須聲明如下:

typedef int (S::*p)() ptr_to_member_of_s; 
5

非靜態成員函數普通函數。你不能形成免費的指針。

唯一允許的方式來指代非靜態成員功能是通過一個實例的指針/參考的和一個指針到成員函數:

S * p = &theobject; 
int (S::*ptmf)() = &S::do_something; 

return (p->*ptmf)(); 

不同於構件對象(你可以非常好地形成一個空閒指針,例如&theobject.x),成員函數更加複雜,因爲你需要考慮虛擬函數:如果S是一個多態基類,並且p是一個指針指針,並且do_something()是虛擬的,那麼上面的例子應該執行正確的派遣類型。一個簡單的免費函數指針不能做到這一點。

(此外,該標準未規定如何的成員函數每個底層實現實現的,所以這個細節不會暴露給用戶。通常它會像int S_mangled_name_do_something(S *);,但沒有指定真實。)

這裏是我的主題的一些相關答案:#1,#2

0
int (S::*p)() = S::do_something; 

非靜態成員函數是一個普通的函數,只是有一個不可見的參數this。

+0

不可見參數只是冰山一角。虛擬調度是一個更嚴重的設計問題。 –

+0

@KerrekSB同意。對於虛函數,我們可以在Lambda表達式中使用std :: function:Base * p =&theObject; \t std :: function func = [&p]() - > int { \t \t return p-> doSomething(); \t};' – BruceAdi

+1

否否否 - '(p - > * ptfm)()'已經處理了正確的分派。我的觀點是成員函數不僅僅是一個帶有隱藏參數的自由函數。 –