向普通函數(shù)傳遞類成員函數(shù)指針的問題
成員函數(shù)func3=>成員函數(shù)func2:
將一個類成員函數(shù)的函數(shù)指針傳遞給另一個成員函數(shù)是比較簡單的,只要定義一個函數(shù)指針就可以輕松實現(xiàn)。示例如下:
using namespace std;
class test
{
public:
typedef void (test::*pFUN)();
void func1()
{
func2(&test::func3); //把func3的指針傳遞給func2
}
void func2(pFUN pfun)
{
(this->*pfun)();
}
void func3()
{
cout<<"test func3."< } }; main() { void (test::*pfun)() = &test::func3; //把func3的指針賦給pfun test my_test; my_test.func1(); my_test.func2(pfun); //把pfun傳遞給func2 cin.get(); } 輸出結果為: test func3. test func3. void fun(void (*pfun)()); 原因: 這是因為類的成員函數(shù)是綁定到對象的,對于不同的對象,成員函數(shù)將會產(chǎn)生不同的拷貝,這樣編譯器就不知道把哪個拷貝傳給fun了。這種情況在很多地方都會遇到,比如OpenCV里面的鼠標事件回調函數(shù): void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param CV_DEFAULT(NULL)); 解決辦法: (1)把這個類改成普通的函數(shù)。這是最笨的辦法。寫成類的好處是可以在成員函數(shù)之間共享一些數(shù)據(jù),如果改成普通的函數(shù),那么就可能會定義一些全局變量來實現(xiàn)共享,而且也不便于管理。 (2)直接把要傳遞的函數(shù)聲明為static類型,比如: static void func3(); 程序如下: using namespace std; class test { public: friend void friend_fun(void *obj); // 聲明一個友元函數(shù) // main中調用外部函數(shù) //void call_fun() //{ // outside_fun(friend_fun, this); // ☆ 把友元函數(shù)的指針和this指針傳遞給外部函數(shù) ☆ //} private: // 私有成員函數(shù) void private_fun() { cout<<"test private_func."< } }; // ☆ 在 友元函數(shù) 中封裝調用 私有成員函數(shù)private_func ☆ void friend_fun(void *obj) { ((test*)obj)->private_fun(); } // ☆ 用友元函數(shù) 優(yōu)于 用static函數(shù) ☆ // 外部的普通函數(shù),接受一個函數(shù)指針和一個void指針作為參數(shù),比如多線程的執(zhí)行函數(shù) void outside_fun(void (*pfun)(void *data), void *data) { (*pfun)(data); } int _tmain(int argc, _TCHAR* argv[]) { test* my_test = new test; //my_test->call_fun(); outside_fun(friend_fun, (void*)my_test); // 暫停 cin.get(); return 0; } 輸出結果為: test private_func. 網(wǎng)絡
版權聲明:本文內(nèi)容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權內(nèi)容。
版權聲明:本文內(nèi)容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權內(nèi)容。