为什么要写this在访问成员变量的时候_C++幕后故事(一) --对象模型this指针调整...
1.什么叫this指針調整?
在c++中多繼承過程,根據訪問不同的父類成員變量或者是成員函數,同一個實例對象會出現不同的基址(對象的地址,類似于你在不同的場合就會有身份的轉換,在家的身份,在學校,在公司的等等),這種現象叫做this指針基址調整。
2.如何調整?
1.如果繼承的順序是A,再B,那么初始化時先A再B,內存布局如下圖1所示。
2. 如果繼承的順序還是是A,再B,那么初始化時的順序不變,還是先A再B,但是B存在virtual function,內存布局如下圖2所示。
3. 如果繼承的順序是A,再B,初始化時還是先A再B,但是A,B同時存在virtual function,內存布局還是如圖1所示,沒有變化。
3.思考:
1.那具體又是怎么調整的?
比如說,繼承A,又繼承B(先不考慮含有virtual fucntion情況)。為了獲取B的成員變量。這是this指針需要偏移字節數為sizeof(A)。從圖1上來看,要先越過A所占用的大小。
2.為什么父類中virtual function,內存布局發生了變化?
因為有了virtual function,類中就需要產生指向一個虛函數表的指針。而虛函數表指針是埋在對象的首地址中。所以B有virtual function,那么B的普通成員變量將會偏移到A的前面。
3.那么既然內存布局發生了變化,但是我們發現只要繼承的順序不變,那么構造的先后順序就不會發生變化。說明構造的先后順序和內存布局沒有任何的關系。
4.既然我們知道了這個this指針的調整,但是有什么用呢?
A.通過指針位置的偏移不就可以訪問了原來編譯器層面阻止你不想訪問的私有屬性。
B.這種解決了多個父類下訪問父類的屬性的解決方案,和多態的方案是非常的相似。
假設在一個家庭中,有你和你爸、你媽。你繼承了你爸你媽的所有的財產。
1.假如,你爸在家里占據中主導地位(類似于你爸包含有虛函數)。那么在你的心目中你爸就在第一位的。
2.假如,你媽在家里占據中主導地位(類似于你媽包含有虛函數)。那么在你的心目中你媽就在第一位的。
3.假如,你爸和你媽在家平分秋色(都包含虛函數或者都不包含虛函數)。那么在你的心目中你爸和你媽,你和誰離得近(繼承的順序,誰先繼承),誰就在第一位的。
4.但是不管是誰在第一位,你家的戶口本上你爸肯定是在第一頁的(構造函數的順序不變)。
5.假如,晚上你們一家三口在床上睡覺,你,你爸,你媽這樣的順序。但是假如你想和你媽睡在一起。你是不是要翻過你爸這座大山(類的大小),才能和你媽睡在一起。(this指針如何調整的)。
6.假如,你想要零花錢,你有兩種方式,一種向你媽要,一種是向你爸要。不管是向誰要,是不是都要先找對對象,才能拿到零花錢。在多繼承中子類有多個父類,所以訪問某個對象的屬性(成員變量,函數),則需要先找到基類的地址,為了找到正確的對象都需要進行地址偏移,這就好像你是找你爸還是找你媽要零花錢都必須先找到這個人。這就是為什么需要調整this指針。
/****************************************************************************打開或者關閉上面的#define VIRTUAL_PARENT_A,#define VIRTUAL_PARENT_B宏,四種結果如下。
OptimizationA oe; OptimizationA of(oe); OptimizationA og = oe; OptimizationA oh = OptimizationA(oe); // 編譯器的角度看,分成兩步走 // 1.OptimizationA of (注意此時不會調用OptimizationA的默認構造函數) // 2.of.OptimizationA::OptimizationA(oe) (調用拷貝構造函數) // 3.og.OptimizationA::OptimizationA(oe) (調用拷貝構造函數) // 4.oh.OptimizationA::OptimizationA(oe) (調用拷貝構造函數)總結
以上是生活随笔為你收集整理的为什么要写this在访问成员变量的时候_C++幕后故事(一) --对象模型this指针调整...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 耦合与内聚的概念
- 下一篇: c语言输出单链表最大值与最小值,数据结构