西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁(yè)編程開(kāi)發(fā)其它知識(shí) → 關(guān)于OO中繼承的思考-深度認(rèn)識(shí)類(lèi),對(duì)象,內(nèi)存分配

關(guān)于OO中繼承的思考-深度認(rèn)識(shí)類(lèi),對(duì)象,內(nèi)存分配

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:本站整理時(shí)間:2010/10/18 14:29:46字體大。A-A+

作者:佚名點(diǎn)擊:84次評(píng)論:0次標(biāo)簽: 繼承 內(nèi)存分配 類(lèi) 對(duì)象

ios星骸繼承者破解版v1.17.3 iPhone/iPad版
  • 類(lèi)型:ios角色扮演大。62.8M語(yǔ)言:中文 評(píng)分:10.0
  • 標(biāo)簽:
立即下載
曾經(jīng)在一本書(shū)中看到過(guò)這樣的一個(gè)問(wèn)題:(語(yǔ)言:C++)

如果兩個(gè)類(lèi),Parent和Child,Child繼承Parent,Parent有一個(gè)函數(shù)print(),有成員變量pVar,Child中有兩個(gè)函數(shù)print(),privatePrint(),有成員變量cVar,

現(xiàn)在 ,申明一個(gè)Parent類(lèi)型的指針來(lái)指向一個(gè)Child的對(duì)象。

那么用這個(gè)指針可以調(diào)用privatePrint()函數(shù)嗎?可以用這個(gè)指針可以調(diào)用成員cVar嗎?

答案是:不能。

那如果Parent中有一個(gè)虛函數(shù)privatePrint(),那么可以調(diào)用到privatePrint()嗎?

答案是:可以。

首先我用C++試了一遍。C++的代碼如下
代碼
1 #include <iostream>
2
3 using namespace std;
4
5 class Prarent
6 {
7 public:
8 Prarent(){};
9 int pVar;
10 void print()
11 {
12 cout<<"I am parent"<< endl;
13 }
14 //virtual void privatePrint(){};
15 };
16
17 class Child : public Prarent
18 {
19 public:
20 Child(){};
21 int cVar;
22 void print()
23 {
24 cout<<"I am child"<< endl;
25 }
26 void privatePrint()
27 {
28 cout<<"I am child' function privatePrint()"<< endl;
29 }
30 };
31
32 void main()
33 {
34 Prarent *parent;
35 Child child; // 原先我竟然寫(xiě)成 Child child = new Child(); 用久了C#, 都是C#惹的禍.
36 parent = &child;
37 parent->print();
38 // parent->privatePrint(); 編譯通不過(guò).
39 // 1: 說(shuō)明父類(lèi)的指針雖然指向了子類(lèi)的對(duì)象, 但是卻不能引用父類(lèi)沒(méi)有申明的函數(shù).
40 // 2: 但是你將privatePrint申明為父類(lèi)的虛函數(shù), 則上面的可以運(yùn)行成功.
41 }
42
43

其實(shí)之前我沒(méi)有怎么在意這個(gè)問(wèn)題。知道My sen Brother問(wèn)了我。我才發(fā)現(xiàn)問(wèn)題并非簡(jiǎn)單。

經(jīng)過(guò)了我們相互的討論之后,我們得到了一種解釋。

我不敢保證一定完全是對(duì)的。但是卻是我們自己的心得和體會(huì)。


理解這個(gè)問(wèn)題。首先要明白兩個(gè)問(wèn)題:1:類(lèi)在內(nèi)存是怎么存放的?(編譯階段實(shí)現(xiàn))2:對(duì)象實(shí)例在內(nèi)存中是怎么存放的?

1:類(lèi)在內(nèi)存是怎么存放的?

我根據(jù)以前Teacher Lei說(shuō)過(guò)的一些內(nèi)容,計(jì)算機(jī)組成,匯編語(yǔ)言,自己看過(guò)一些書(shū),得到自己的一種思考。

其中一個(gè)類(lèi),通過(guò)編譯分別存在內(nèi)存的兩塊地方,一個(gè)是代碼段,一個(gè)是數(shù)據(jù)段;

代碼段存放一個(gè)類(lèi)的成員變量;(ie. 上面的pVar和cVar都是存放在代碼段中)

數(shù)據(jù)段存放一個(gè)類(lèi)的成員函數(shù)表;(ie. 上面的print()和privatePrint()都存放于這里);

數(shù)據(jù)段中的每一個(gè)類(lèi)的內(nèi)存塊應(yīng)該由兩個(gè)表填充,一個(gè)為虛函數(shù)表,一個(gè)為非虛函數(shù)表;

數(shù)據(jù)段中類(lèi)的成員變量存放,如下:

int pVar

int cVar


代碼段中類(lèi)的成員函數(shù)表存放,如下:
Parent()

Print()

Child()

Print()

pravtePrint()


下面來(lái)解釋 2:對(duì)象實(shí)例在內(nèi)存中是怎么存放的?

我們拿上面的例子來(lái)說(shuō)明:

當(dāng)初始化一個(gè)Parent *parent 一個(gè)指針對(duì)象時(shí),這時(shí)候parent所指向的地址就是100;


vPtr(虛函數(shù)指針) 地址:100

int pVar

當(dāng)初始化一個(gè)Child類(lèi)型 child 對(duì)象時(shí),這時(shí)候child的地址就是200;(注意和指針不一樣)

vPtr(虛函數(shù)指針) 地址:200

int pVar

int cVar


首先:為什么這邊一定是這樣排列的

還記得Teacher Lei說(shuō)過(guò)嗎?原因:子類(lèi)在初始化的時(shí)候是先調(diào)用父類(lèi)的構(gòu)造函數(shù)!!

說(shuō)明父類(lèi)的成員一定是先被初始化的。

所以這邊的結(jié)構(gòu)必然是這樣的。(這里很重要)

好了。到現(xiàn)在基本就把要知道的基礎(chǔ)知識(shí)解決了。

不知道讀著博客的人累了沒(méi)有。。呵呵。后面的更精彩。



現(xiàn)在 把child對(duì)象的地址賦值給指針parent(即 parent = &child)

先來(lái)看看 parent->cVar 為什么不行?!

第一步:parent->cVar 其實(shí)是一個(gè)地址的偏移過(guò)程,現(xiàn)在parent的地址是200;那么cVar就代表2個(gè)偏移量;

按說(shuō)電腦是可以找到202的這個(gè)地址的值?墒菫槭裁床恍心?

第二步:在程序的編譯過(guò)程中,每一個(gè)的成員函數(shù)名都被當(dāng)做一個(gè)偏移量。

就像這里,pVar代表量1個(gè)偏移。cVar代表2個(gè)偏移量。

第三步:parent是Parent類(lèi)型的。這個(gè)很關(guān)鍵。因?yàn)樵诰幾g的以后,parent已經(jīng)初始化了一個(gè)最大偏移量max (這里的max為1)

第四步:結(jié)果已經(jīng)很明顯了。因?yàn)閜arent的最大偏移量max 為1。程序根本找不著偏移量為2的變量地址。


然后看看 parent->privatePrint() 為什么不行?
還是那個(gè)關(guān)鍵點(diǎn)。parent是Parent類(lèi)型的,還記得上面說(shuō)類(lèi)在內(nèi)存中的加載方式嗎?parent指向的是Parent的內(nèi)存塊。所以在那個(gè)內(nèi)存塊中,根本找不著privatePrint()這個(gè)函數(shù)。

可是?有人因?yàn)闀?huì)問(wèn)了?為什么如果在Parent中申明了一個(gè)虛函數(shù)類(lèi)型的privatePrint()就可以了呢?

還記得類(lèi)的實(shí)例在內(nèi)存中加載的那個(gè)圖嗎?每個(gè)類(lèi)的前面都有一個(gè)的vPtr虛函數(shù)指針,他指向的是當(dāng)前類(lèi)的虛函數(shù)表。通過(guò)虛函數(shù)表中的privatePrint()也相當(dāng)一個(gè)指針,指向了子類(lèi)中實(shí)現(xiàn)父類(lèi)虛函數(shù)的privatePrint(),自然就能找到了。

此時(shí)一切真相大白。
    星骸繼承者
    (9)星骸繼承者
    星骸繼承者西西專區(qū)為您提供該游戲的破解版電腦版蘋(píng)果版輔助修改器等相關(guān)下載助你在游戲中能夠玩的更加的愉快快來(lái)下載游戲體驗(yàn)吧星骸繼承者簡(jiǎn)介星骸繼承者是款以星際逃亡為背景,與異星生物協(xié)同作戰(zhàn),反抗侵蝕宇宙的恐怖黑暗生命體的科幻向手游。每個(gè)人都有一個(gè)星際夢(mèng),不管是對(duì)異星的向往還是對(duì)未知的探索在科技日益發(fā)達(dá)的未來(lái)世界,人類(lèi)已經(jīng)能夠成功的在宇宙中發(fā)展殖民行星。然而,宇宙中強(qiáng)大的黑暗生物迷之生命體塔拉劫多襲擊了...更多>>
    • 星骸繼承者官網(wǎng)v1.0 安卓版

      10-13 / 55.1M

      推薦理由:星骸繼承者是一款日系奇幻風(fēng)格的扮演類(lèi)手機(jī)游戲,近未來(lái)科幻背景題材,為了生存抵御外星人,任務(wù)玩法多樣精
    • 星骸繼承者內(nèi)購(gòu)破解版v1.0 安卓版

      10-13 / 55.1M

      推薦理由:星骸繼承者破解版是一款神秘的魔幻風(fēng)扮演類(lèi)RPG游戲,全3D超清畫(huà)質(zhì)打造,超酷炫多視角旋轉(zhuǎn)鏡頭捕捉技術(shù),拳拳
    • 星骸繼承者電腦版v1.0

      10-13 / 55.1M

      推薦理由:星骸繼承者電腦版是一款精美的日系RPG扮演類(lèi)手機(jī)游戲,高清細(xì)膩的視網(wǎng)膜畫(huà)面技術(shù),帶來(lái)極致精美的Q
    • ios星骸繼承者破解版v1.17.3 iPhon

      10-13 / 62.8M

      推薦理由:ios星骸繼承者破解版是一款史詩(shī)級(jí)的科幻手游大作,宏大的歷史背景世界觀,超高清的星際逼真場(chǎng)景,視覺(jué)聽(tīng)覺(jué)雙
    • 燒餅游戲修改器V3.1 最新版

      01-29 / 970KB

      推薦理由:《燒餅游戲修改器SBgametool》是迄今為止Android平臺(tái)上最簡(jiǎn)單好用的游戲修改工具(沒(méi)有之一),精小,快速,綠
    • 叉叉助手2.5.1 官方安卓版

      12-14 / 24.5M

      推薦理由:叉叉助手輔助憑著天天酷跑游戲贏得了好多的用戶,現(xiàn)在叉叉助手升級(jí)管理輔助,之前單個(gè)游戲叉叉助手歷史版本

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過(guò)難過(guò)
    • 5 囧
    • 3 圍觀圍觀
    • 2 無(wú)聊無(wú)聊

    熱門(mén)評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)