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