深度探索C++物件模型(2)——物件(2)
this指標調整
首先看程式碼示例:
#include <iostream> using namespace std; class A { public: int a; A() { printf("A::A()的this指標是:%p!\n",this); } void funA() { printf("A::funA()的this指標是:%p!\n",this); } virtual void fun() { } }; class B { public: int b; B() { printf("B::B()的this指標是:%p!\n", this); } void funB() { printf("B::funB()的this指標是:%p!\n", this); } }; class C: public A,public B //注意繼承順序,決定了後面的記憶體佈局 { public: int c; C() { printf("C::C()的this指標是:%p!\n", this); } void funC() { printf("C::funC()的this指標是:%p!\n", this); } }; int main() { cout << sizeof(A) << endl; cout << sizeof(B) << endl; cout << sizeof(C) << endl; C myc; myc.funA(); myc.funB(); myc.funC(); return 0; }
visual studio2017執行結果:
解釋:
(1)A類物件:非靜態成員變數a佔4個位元組,虛擬函式表指標佔4個位元組,共8個位元組
B類物件:非靜態成員變數b佔4個位元組
C類繼承自A類和B類:它的非靜態成員變數有 int a; int b; int c;,所以12個位元組()
(2)對於子類物件,它是包含父類物件的,會先為其父類物件成員連續分配記憶體空間,而且分配順序按照其繼承順序進行,
如上面的例子中先依次連續分配父類物件A,B,子類物件C的記憶體空間
(3)對於它的父類物件的this也就指向它本身所在記憶體空間的首地址,而對於子類物件的this它是指向第一個父類物件的首地址
所以上面的例子中父類物件A和B的this指標都指向它們各自的記憶體空間,而子類物件C的this指標指向A的記憶體空間首地址
圖示理解:
修改程式碼如下:讓C類重寫父類B中的funB()函式
#include <iostream> using namespace std; class A { public: int a; A() { printf("A::A()的this指標是:%p!\n",this); } void funA() { printf("A::funA()的this指標是:%p!\n",this); } virtual void fun() { } }; class B { public: int b; B() { printf("B::B()的this指標是:%p!\n", this); } void funB() { printf("B::funB()的this指標是:%p!\n", this); } }; class C: public A,public B //注意繼承順序,決定了後面的記憶體佈局 { public: int c; C() { printf("C::C()的this指標是:%p!\n", this); } void funC() { printf("C::funC()的this指標是:%p!\n", this); } void funB() { printf("C::funB()的this指標是:%p!\n", this); } }; int main() { cout << sizeof(A) << endl; cout << sizeof(B) << endl; cout << sizeof(C) << endl; C myc; myc.funA(); myc.funB(); myc.B::funB(); myc.funC(); return 0; }
結果:
解釋:
你呼叫哪個子類的成員函式,這個this指標就會被編譯器自動調整到物件記憶體佈局中 對應該子類物件的起始地址那去;
這裡由於在C類中重寫了funB(),所以myc.funB()會呼叫C中的funB,所以此時this指向C物件的起始地址
而在呼叫myc.B::funB()時,呼叫的是B中的funB,所以此時this指向B物件的起始地址
相關推薦
【深度探索C++物件模型】(2.5)bitwise和memberwise
在看《深入探索C++物件模型》這本書的時候,我看見了bitwise senimatics和memberwise senimatics,看的時候還不清楚這兩個是什麼意思,書本上直接使用的是英文,所以我的直譯就是位逐次語意和成員逐次語意,經過一番百度後才發現原來就是簡單的淺拷貝和深拷貝的區別。
深度探索C++物件模型(2)——物件(2)——this指標調整
this指標調整 首先看程式碼示例: #include <iostream> using namespace std; class A { public: int a; A() { printf("A::A()的this指標是:%p!\n",this); } v
深度探索C++物件模型(2)——物件(2)
this指標調整 首先看程式碼示例: #include <iostream> using namespace std; class A { public: int a; A() { printf("A::A()的this指標是:%p!\n",thi
深度探索C++物件模型(1)——物件(1)
(1)一個類物件至少佔用一個位元組的記憶體空間,哪怕是一個空類 為什麼sizeof(空類)=1,而不等於0?
【深度探索C++物件模型】(1)關於物件
哎 再開新坑,希望19年能把開的這幾個坑都填上。 class : 類 class object : 類物件 1 C++物件模型 簡單來說,C++物件模型的例項的組成包括下面幾個部分: Nonstatic data members與**virtual pointer(vpt
《深度探索c++物件模型》筆記總結(一)
首先先明確一個宗旨及兩個概念: 宗旨:C++在佈局及存取時間上主要的額外負擔是由virtual引起的 1.虛擬函式:C++多型的基本實現,沒什麼好說的,詳細見如下打包筆記:虛擬函式 2.虛基類:用來處理菱形繼承時候,在派生類中資料有重複的問題,見筆記:虛基類 ------------
《深度探索C++物件模型》學習總結(一)——前言與導讀
前言 Foundation專案:為了構建大系統而努力定義的一個新的開發模型。 ALF:一種一面物件層次結構,提供一個永久的、以語意為基礎的表現法。 Simplifier的工作:轉換內部的程式表現。 任何物件模型都需要的轉換風味(?): 1. 與
《深度探索C++物件模型》讀書筆記(一)
Lippman早期在貝爾實驗室,和C++發明者Bjarne Stroustrup設計了全世界第一套C++編譯器cfront,還著有經典的C++入門書Ensential C++和C++ Primer。 全書基本以cfront的設計方法為基礎,討論編譯器如何處理C
深度探索C++物件模型——物件(5)——程式轉化語義
我們寫的程式碼,編譯器會對程式碼進行拆分,拆分成編譯器更容易理解和實現的程式碼,接下來將從我們程式設計師寫程式碼角度和編譯器理解角度去分析一些情況 1.定義時初始化物件 (1)程式設計師角度 #include <iostream> using namespace std;
深度探索C++物件模型(4)——物件(4)——拷貝建構函式語義
傳統認識認為:如果我們沒有定義一個自己的拷貝建構函式,編譯器會幫助我們合成 一個拷貝建構函式。 結論:這個合成的拷貝建構函式,也是在 必要的時候才會被編譯器合成出來。 示例程式碼 class A { public
深度探索C++物件模型(3)——物件(3)——建構函式語義
預設建構函式(預設建構函式)分析 即沒有引數的建構函式 傳統認識認為:如果我們自己沒定義任何建構函式,那麼編譯器就會為我們隱式自動定義 一個預設的建構函式, 我們稱這種建構函式為:“合成的預設建構函式” &n
深度探索C++物件模型——物件(7)——成員初始化列表
1.何時必須使用成員初始化列表 (1)如果初始化的成員是個引用 這裡拋個問題留作後面補充總結的連結:在類中使用引用成員變數的作用? #include <iostream> using namespace std; class A { public: int a; int
《深度探索C++物件模型》筆記(三)建構函式、拷貝構造和初始化列表
歡迎檢視系列部落格: -------------------------------------------------------------------------------------------------------------- 看了這一章
深度探索C++對象模型讀書筆記(一)
復雜 理解 image play 基礎上 isp 靜態 布局 bject 《深度探索C++對象模型》這本書也算是學習C++面向對象編程的必備書了,打算花上幾天先簡單的看一遍,這種書看上好幾遍也不一定能理解太多,慢慢積累一點一滴吃透就好。下面把我看書過程中覺得比較有意義的摘錄
深入探索C++物件模型(九) 解構函式 (以及顯式定義的解構函式問題、解構函式Rules of Three)
如果類沒有定義解構函式,那麼只有類中含有成員物件(或者本類的基類)擁有解構函式的情況下,編譯器才會合成一個出來,否則解構函式被視為不要,也就不需要合成。例如,如下類,雖然Point類擁有虛擬函式:class Point { piblic: Point(flo
C++物件模型之記憶體佈局三(虛繼承)
經過兩天的摸索,今天終於搞清楚C++物件模型.前兩篇已經講解了單繼承,多重繼承和多繼承的物件模型.今天講解菱形繼承,雖然過程艱難,但是收穫豐富. 簡單虛繼承物件模型 首先編寫如下的測試程式: 1
深度探索 C++ 物件模型 03:資料成員
即使一個類表面上是空的,它也內含一個隱式的 char,從而確保這個類的任意兩個 object 不會在記憶體中佔用相同的地址 類的 nonstatic data member 放置其各個 object 感興趣的資料,而類的 static data member
《深度探索C++物件模型》.pdf
書籍簡介: 《深度探索C++物件模型》探索“物件導向程式所支援的C++物件模型”下的程式行為。對於“物件導向性質之基礎實現技術”以及“各種性質背後的隱含利益交換”提供一個清楚的認識。檢驗由程式變形所帶來的效率衝擊。提供豐富的程式範例、圖片,以及物件導向觀念和底層物件模型之
深度探索C++物件模型--之物件的差異加上多型之後
class zooAnimal{ public: zooAnimal(); virtual ~zoonAnimal(); virtual void rotate(); protected: int loc; string name; }; class Bear :public zooAn
深度探索C++物件模型筆記《指標的型別》
一個指標,不管它指向哪一種資料型別,指標本身所需的記憶體大小是固定的,即4個位元組。 class Z{ //...... }; class X: public Z{ //...... }; 那麼X* Px; Z *Pz; int* Pi;又有何不同呢?