關於C++虛函數的一些具體介紹,參見博客虛函數表解析(轉至陳皓),就其中涉及的一些問題與大家分享一下。 先來看一段代碼:
#include <iostream> using namespace std; typedef void (*Fun)(void); class BaseA { public: virtual void A1(){cout<<"A1"<<endl;} virtual void A2(){cout<<"A2"<<endl;} virtual void A3(){cout<<"A3"<<endl;} }; class BaseB { public: virtual void B1(){cout<<"B1"<<endl;} virtual void B2(){cout<<"B2"<<endl;} virtual void B3(){cout<<"B3"<<endl;} }; class BaseC:public BaseA,public BaseB { public: virtual void A1(){cout<<"C.A1"<<endl;} virtual void A2(){cout<<"C.A2"<<endl;} virtual void A3(){cout<<"C.A3"<<endl;} virtual void B1(){cout<<"C.B1"<<endl;} virtual void B2(){cout<<"C.B2"<<endl;} virtual void B3(){cout<<"C.B3"<<endl;} private: virtual void C1(){cout<<"C1"<<endl;} virtual void C2(){cout<<"C2"<<endl;} virtual void C3(){cout<<"C3"<<endl;} }; int main() { Fun fun=NULL; BaseA* baseA1 = new BaseC; BaseB* baseB1 = new BaseC; BaseA* baseA2 = (BaseA*)(void*)baseB1; BaseB* baseB2 = (BaseB*)(void*)baseA1; cout<<"baseA1->A1()=";baseA1->A1(); cout<<"baseB1->B1()=";baseB1->B1(); cout<<"baseA2->A1()=";baseA2->A1(); cout<<"baseB2->B1()=";baseB2->B1(); fun= (Fun)*((int*)*(int*)(baseA1)+3); fun(); //system("pause"); return 0; }
這裡有必要首先解釋一下 typedef void (Fun*)(void);這部分摘自百度知道http://zhidao.baidu.com/link?url=FfhL3LI823olsaln6p-KBKU-BercosGNFxgIpaMNS_ErverXjrenlu1n3NfBd75qfwdw170Aljmk-8YkdaraPa 定義一個函數指針類型。 比如你有三個函數: void hello(void) { printf("你好!"); } void bye(void) { printf("再見!"); } void ok(void) { printf("好的!"); } typdef void (*funcptr)(void); 這樣就構造了一個通用的函數 你用的時候可以這樣: void speak(int id) { funcptr words[3] = {&hello, &bye, &ok}; funcptr fun = words[id]; (*fun)(); } 這樣的話,如果speak(0)就會顯示“你好!” speak(1)就會顯示“再見!” speak(2)就會顯示“好的!” 用於處理參數和返回值的形式都一樣,但是功能不確定的一組函數,可以使用函數指針。 比如算術運算符,加、減、乘、除,都可以用typedef int (*calc)(int,int)代表,等等 /***************************************************************************************************************************************************************/ 結果會顯示什麼呢? baseA1->A1()=C.A1 baseB1->B1()=C.B1 baseA2->A1()=C.B1 baseB2->B1()=C.A1 C1 為什麼baseA2->A1() =C.B1? 為什麼baseB2->B1()=C.A1? 相信了解C++虛函數機制 都明白是怎麼回事 重點我們放在 fun() 上,顯示結果為C1! 不知有木有看到,在類BaseC中的C1是聲明在private域中的,但是我們卻可以通過操作BaseA1來訪問私有函數,(至於為什麼可以訪問,再次建議先閱讀轉載文章,理清C++虛函數的機制) ,這一點足見C++在安全性上的考慮是欠缺的,至少可以說是不嚴謹的。