成員函數指針作爲形參調用


平安2010

[新手]
已解決 

c++編譯錯

50分
標籤:c++ 編譯 test 程序編譯 桌面 
回答:3   瀏覽:609   提問時間:2010-03-02 10:37
#include <stdio.h> 
class Man 

private: 
typedef struct sAct{ 
void (*Func)(); 
sAct(){Func = NULL;} 
}sAct; 
protected: 
sAct *m_Act; 
public: 
Man(){m_Act = NULL;} 
void Move(){;} 
void ActionSet(void (*Func)()){;} 
}; 
int main() 

Man man; 
man.ActionSet(man.Move); 
return 0; 


這個程序編譯後,錯誤是: 
C:/Documents and Settings/microsoft/桌面/test/main.cpp(21) 
: error C2664: 'ActionSet' : cannot convert parameter 1 from 'void (void)' to 'void (__cdecl *)(void)' 
None of the functions with this name in scope match the target type 
把void Move(){;}改成static void Move(){;}後編譯成功,爲什麼啊?
最佳答案 最佳答案 此答案由提問者自己選擇,並不代表愛問知識人的觀點

憶夢瀟湘

[學長] 向憶夢瀟湘提問
成員函數是this call的, 調用的時候默認會將this指針作爲函數最後一個參數;而靜態成員函數通過靜態,脫離了this,所以是可以強轉爲一般函數指針的,也就是上面的cdecl。 
如果你想保存成員函數爲一般函數指針,並像普通函數那樣用,那就只有聲明其爲靜態一種方式。 

另外針對你的例子,不改成static的方式是如下的: 


#include <stdio.h> 
class Man 

private: 
typedef struct sAct{ 
void (*Func)(); 
sAct(){Func = NULL;} 
}sAct; 
protected: 
sAct *m_Act; 
public: 
Man(){m_Act = NULL;} 
void Move(){;} 
void ActionSet(void (Man::*Func)()){;} 
}; 
int main() 

Man man; 
man.ActionSet(&Man::Move); 
return 0; 


ps:請使用最新的編譯器,以方便查錯: 
我的vs2008是這麼寫的,明顯多了: 
error C2664: “Man::ActionSet”: 不能將參數 1 從“void (__thiscall Man::* )(void)”轉換爲“void (__cdecl *)(void)”
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章