2011-12-20 101 views
3

當我需要一個指向類的成員,我做如下澄清指向非靜態類成員

struct MyStruct 
{ 
    int foo(); 
}; 

int (MyStruct::*p)() = &MyStruct::foo; 

我的問題是,爲什麼我需要使用&運營商採取何種可能的地址如果它是一個靜態函數,則被忽略。另外,我聽過指向成員的指針並不是真正的指針,有人可以澄清一下嗎?

回答

6

如果它是一個靜態函數,它就像普通的非成員函數指針一樣工作:函數名稱本身可以隱式轉換爲函數指針。

如果它是一個非靜態成員函數,它不再是同樣的事情,作爲一個非成員函數:

  1. 它有一個隱藏this參數;
  2. 在多重繼承的情況下,將指針轉換爲其中一個基類可能會產生指向不同地址的指針。這意味着如果成員函數被繼承,則可能需要在調用之前調整指針this。這已經使得不可能使用指針來存儲指向成員函數的指針。

Raymond Chen wrote an interesting article關於此更多的細節和示例。

+0

Agree.And非成員函數指針的地址可在編譯時加以解決。但是,對於成員函數指針,其地址將在運行時解析,例如虛函數。所以它不能使用單個地址來呈現指向成員函數的指針 – RolandXu 2011-12-20 06:46:30

-2

爲什麼我需要使用&操作人員採取可 忽略,如果它是一個靜態函數

你是對的,在指針的成員函數的語法非常&的情況下地址可以省略。我認爲,&語法是有可能是由於歷史慣例。

我聽過指向成員的指針並不是真的指針,有人可以澄清一下嗎?

這是不正確的。唯一的區別是它們是指向成員函數的指針。由於class非靜態成員包含一個隱式this指針作爲它們的參數,它們有一個特殊的簽名。而且,它們不能與具有相同簽名的普通函數指針相互轉換。

在您的代碼示例,theoritically p指向:

int MyStruct::foo (MyStruct* const); 
+2

static_assert(!std :: is_pointer :: value,「指向成員函數的指針不是一個指針「);'。 – 2011-12-20 06:45:47