日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【讨论贴】关于父实子虚的疑问???

發(fā)布時(shí)間:2025/3/21 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【讨论贴】关于父实子虚的疑问??? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

關(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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。