【讨论贴】关于父实子虚的疑问???
關于這篇文章,還沒有得到最后答案,只是在這里記錄一筆,但是歡迎討論~~將來解決了問題,再專門出貼解答~
父實子虛就是:父類非虛函數,子類繼承變成虛函數,會發生什么
昨天就提問了,但是沒有滿意的答案,地址:http://ask.csdn.net/questions/198077
想法很奇葩,運行結果更是奇葩,大家看應該怎么解釋一下,運行環境是vs2012 release Win32平臺
代碼:
#include<iostream> using namespace std;class A { public:void foo(){printf("A類中:實foo()\n");}virtual void fun(){printf("A類中:虛fun()\n");} };class B : public A { public:virtual void foo(){printf("B類中:虛foo()\n");}void fun(){printf("B類中:實fun()\n");} };class C : public B { public:void foo(){printf("C類中:實foo()\n");}void fun(){printf("C類中:實fun()\n");} };int main(void) {A a;B b;A *ap = &a;ap->foo(); //父實子虛ap->fun(); //父虛子實cout<<endl;ap = &b;ap->foo();ap->fun();cout<<endl;cout<<"???"<<endl;B *ptr = (B *)&a;ptr->foo(); //為什么是cptr->fun(); //為什么是ccout<<endl;C oc;B *bp = &b;bp->foo();bp->fun();cout<<endl;bp = &oc;bp->foo();bp->fun(); //為什么不是B中cout<<endl;return 0; } 運行結果:
考慮可能是第三組強制轉換的問題,于是采用dynamic cast,果然出錯。
即使刪掉第三組測試,但是問題依然存在
附:
在c++的世界中有這樣兩個概念,向上類型轉換,向下類型轉換,分別描述的是子類向基類,和基類向子類的強制類型轉換。
向上強制類型轉換
切割:覆蓋方法和子類數據丟失的現象生成切割(slice)
class Base { public: int b; virtual void Test() { cout << "base" <<endl; } }; class Derived:public Base { public: int d; virtual void Test() { cout << "derived" <<endl; } }; int main() { Derived d; Base b = d;//直接賦值(產生切割) b.Test(); Base& b2 = d;//使用引用賦值(不產生切割) b2.Test(); Base* b3 = &d;//使用指針賦值(不產生切割) b3->Test(); return 1; }
?
因此,我們得出結論,在向上強制轉換過程中,使用指針和引用不會造成切割,而使用直接賦值會造成切割。
?
向下強制類型轉換
使用dynamic_cast進行向下強制類型轉換。使用此關鍵字有一下幾個條件
1.必須有虛函數
2.必須打開編譯器的RTTI開關(vc6: progect-> settings -> c/c++ tab ->category[c++ language]-> Enable RTTI)
3.必須有繼承關系
Base *b = new Derived; Derived *d = dynamic_cast<Derived*>(b); if(!d) { cout << "dynamic cast err!"<<endl; } else { d->Test(); }
?
?本例子中,符合以上條件,轉換成功。否則,會拋出std::bad_cast異常,轉換返回NULL
因此,我們可以使用dynamic_cast來判斷兩個類是否存在繼承關系?
總結
以上是生活随笔為你收集整理的【讨论贴】关于父实子虚的疑问???的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android视频播放之VideoVie
- 下一篇: 【转】做产品VS做项目