在編程工作中常會遇到在一個“類”中通過函數指針調用成員函數的要求,如,當在一個類中使用了C++標準庫中的排序函數qsort時,因qsort
參數需要一個“比較函數”指針,如果這個“類”使用某個成員函數作“比較函數”,就需要將這個成員函數的指針傳給qsort供其調用。本文所討論的用指針
調用 “類”的成員函數包括以下三種情況:
?。?).將 “類”的成員函數指針賦予同類型非成員函數指針,如:
例子1
#include <stdlib.h> typedef void (*Function1)( ); //定義一個函數指針類型。 Function1 f1; class Test1 { public: //…被調用的成員函數。 void Memberfun1( ){ printf(%s \n,Calling Test3::Memberfun2 OK);}; // void Memberfun2() { f1=reinterpret_cast<Function1>(Memberfun1);//將成員函數指針賦予f1。編譯出錯。 f1(); } //… }; int main() { Test1 t1; t1.Memberfun2(); return 0; } |
#include <stdlib.h> class Test2 { private: int data[2]; //… public: //… int __cdecl Compare(const void* elem1, const void* elem2) //成員函數。 { printf(%s \n,Calling Test2::Memberfun OK); return *((int*)elem1)- *((int*)elem2) ; } void Memberfun() { data[0]=2; data[1]=5; qsort( data, 2, sizeof(int), Compare); //標準庫函數調用成 //員函數。編譯出錯。 } //… }; int main( ) { Test2 t2; t2.Memberfun(); //調用成員函數。 return 0; } |
[NextPage]
?。?)同一個“類”內,一個成員函數調用另一個成員函數, 如:
例子3:
#include stdlib.h class Test3 { public: //… void Memberfun1( void (* f2)( ) ) { f2( ) ;} //成員函數1調用成員函數//2。 void Memberfun2( ) { printf(%s \n,Calling Test3::Memberfun2 OK);} //成員函數2。 void Memberfun3( ) { Memberfun1( Memberfun2);} // 編譯出錯 //… }; int main( ) { Test3 t3; t3.Memberfun3(); //調用成員函數。 return 0; } |
#include <stdlib.h> void Memberfun1( void (* f2)( ) ) { f2( ) ;} //原成員函數1調用成員函數//2。 void Memberfun2( ) { printf(%s \n,Calling Test3::Memberfun2 OK);} //原成員函數2。 void Memberfun3( ) { Memberfun1( Memberfun2);} int main( ) { Memberfun3 (); return 0; } |
#include stdafx.h #include <iostream> #include <typeinfo.h> class Test; //一個未定義的類。 class Test2 //一個空類。 { }; class Test3 //一個有定義的類。 { public: //... void (* memberfun)(); void Memberfun1( void (* f2)( ) ) { f2( ) ;} //成員函數1調用成員函數//2。 void Memberfun2( );//成員函數2。 //… }; class Test4: virtual Test3 ,Test2 //一個有virtual繼承的類(derivative class)。 { public: void Memberfun1( void (* f2)( ) ) { f2( ) ;} }; class Test5: Test3,Test2 //一個繼承類(derivative class)。 { public: void Memberfun1( void (* f2)( ) ) { f2( ) ;} }; int main() { std::cout <<一般函數指針長度= << sizeof(void(*)()) << '\n'; std::cout <<-類的成員函數指針長度-<<'\n'<<'\n'; std::cout <<Test3類成員函數指針長度=<< sizeof(void(Test3::*)())<<'\n'<<'\n'; std::cout <<Test5類成員函數指針長度=<<sizeof(void (Test5:: *)())<<'\n'; std::cout <<Test4類成員函數指針長度=<<sizeof(void (Test4:: *)())<<'\n'; std::cout <<Test類成員函數指針長度=<<sizeof(void(Test::*)()) <<'\n'; return 0; } |
[NextPage]
那么,當需要時,如何用指針調用類的成員函數?可以考慮以下方法:
?。?) 將需要調用的成員函數設為static 類型,如:在前述例子2中,將class Test2 成員函數Compare 定義前加上static 如下(黑體為改變之處):
class Test2 { //…. int static __cdecl Compare(const void* elem1, const void* elem2) //成員函數。 //其他不變 } |
class Test3 { public: //… void static __cdecl Helper(Test3* test3) { test3->Memberfun2(); } void Memberfun1( void (* f2)(Test3*)) { f2(this) ;} //將對象信息傳給Helper函數。 void Memberfun2( ) {printf(%s \n,Calling Test3::Memberfun2 OK); } //成員函數2。 void Memberfun3( ) { Memberfun1( Helper);} //… }; |
class Test3; void __cdecl Helper(Test3* test3); class Test3 { public: //… void Memberfun1( void (* f2)(Test3*)) { f2(this) ;} //成員函數1調用成員函數//2。 void Memberfun2( ) {printf(%s \n,Calling Test3::Memberfun2 OK); } //成員函數2。 void Memberfun3( ) { Memberfun1( Helper);} //… }; void __cdecl Helper(Test3* test3) { test3->Memberfun2(); }; |
原文轉自:http://www.anti-gravitydesign.com