文章目錄
- C++面向?qū)ο缶幊蹋ㄏ拢?/li>
- 11. vtpr(virtual pointer)和vtbl(virtual table)
- 1. 前提須知
- 2. 靜態(tài)綁定和動態(tài)綁定
- 3. vtpr和vtbl
- 4. 多態(tài)
- 5. 圖示一
- 6. 圖示二
- 7. template method補(bǔ)充
- 12. const member functions(常量成員函數(shù))
- 1. 形式(const加的位置):
- 2. member functions 與 object 的規(guī)則
- 3. const member functions 和 non-const member functions 的特殊規(guī)則
- 13. 重載operator new、delete、 new[]、delete[]
- 1. 知識回顧
- 2. 重載 ::operator new、new[] 和 ::operator delete、delete[]
- 3. 重載 member operator new 和 member operator delete
- 4. 重載 member operator new[] 和 member operator delete[]
- 5. operator new、delete、 new[]、delete[] 使用示范
- 1. member operator new、delete、 new[]、delete[]重載寫法
- 2. member operator new、delete、 new[]、delete[]調(diào)用過程
- 3. 顯式調(diào)用global operator new、delete、 new[]、delete[]過程
- 14. 重載member operator new(...) 、 delete(...)
- 1. new(...) 、delete(...)和new、delete的區(qū)別
- 2. member operator new(...)
- 3. member operator delete(...)
- 4. member operator new(...)、delete(...)重載書寫和使用
- 5. 標(biāo)準(zhǔn)庫string重載placement new
網(wǎng)站建設(shè)公司,為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計(jì)及定制網(wǎng)站建設(shè)服務(wù),專注于
成都定制網(wǎng)頁設(shè)計(jì),高端網(wǎng)頁制作,對
戶外休閑椅等多個行業(yè)擁有豐富的網(wǎng)站建設(shè)經(jīng)驗(yàn)的網(wǎng)站建設(shè)公司。專業(yè)網(wǎng)站設(shè)計(jì),網(wǎng)站優(yōu)化推廣哪家好,專業(yè)
seo優(yōu)化排名優(yōu)化,H5建站,響應(yīng)式網(wǎng)站。C++面向?qū)ο缶幊蹋ㄏ拢?
11. vtpr(virtual pointer)和vtbl(virtual table)
1. 前提須知
- 實(shí)例對象在內(nèi)存的表現(xiàn):
- 函數(shù)在內(nèi)存中的位置,與實(shí)例對象占用的內(nèi)存沒有關(guān)系;
- 對于一個類的多個對象,函數(shù)在內(nèi)存中也只會有一份;
- 實(shí)例對象占用的內(nèi)存,只會包含對象的數(shù)據(jù);如果有虛函數(shù),還會包含一個虛指針;【無論有多少個虛函數(shù),都只會多占用一個指針的空間;】
- 繼承:
- 對于父類中的函數(shù),子類只是繼承了函數(shù)的調(diào)用權(quán),不會為子類在內(nèi)存中另外生成一份函數(shù)【因?yàn)楹瘮?shù)始終只在內(nèi)存占一份】;
- 如果父類有虛函數(shù),那么子類也一定有虛函數(shù)(繼承);
- 雖然父類和子類中的非虛函數(shù)和數(shù)據(jù),命名可以重復(fù)(因?yàn)槎邲]有什么關(guān)系),但這樣的命名風(fēng)格不好。
2. 靜態(tài)綁定和動態(tài)綁定
- 類型:
- 靜態(tài)類型:對象在聲明時采用的類型,在編譯期既已確定;
- 動態(tài)類型:通常是指一個指針或引用目前所指對象的類型,是在運(yùn)行期決定的;
- 綁定(Binding):是指將變量和函數(shù)名轉(zhuǎn)換為地址的過程。
- 靜態(tài)綁定:綁定的是靜態(tài)類型,所對應(yīng)的函數(shù)或?qū)傩砸蕾囉趯ο蟮撵o態(tài)類型,發(fā)生在編譯期;
- 意味著綁定的函數(shù)或者變量,已經(jīng)在編譯階段,該語句已經(jīng)被編譯成“call 函數(shù)地址”或"callq 函數(shù)地址"這樣的匯編指令格式,并且這些匯編指令中的函數(shù)地址在程序編譯后是固定不變的,請記住,所有函數(shù)都有唯一的地址。
- 動態(tài)綁定:綁定的是動態(tài)類型,所對應(yīng)的函數(shù)或?qū)傩砸蕾囉趯ο蟮膭討B(tài)類型,發(fā)生在運(yùn)行期;
- 只有虛函數(shù)才使用的是動態(tài)綁定(實(shí)現(xiàn)多態(tài)),其他的全部是靜態(tài)綁定;
- 編譯器使用動態(tài)綁定的三個條件:
- 通過指針 / 引用調(diào)用函數(shù);
- 指針是向上轉(zhuǎn)型后的指針(this指的是子類對象,符合向上轉(zhuǎn)型);【即父類指針指向子類對象】
- 指針調(diào)用的是虛函數(shù)。
- 簡單一句話:
使用基類的引用(指針)調(diào)用虛函數(shù)
3. vtpr和vtbl
vtpr(虛指針):
- 對于有virtual函數(shù)的類,它的實(shí)例化對象在內(nèi)存空間中除了包含數(shù)據(jù)的大小,還會多出一個指針(4個字節(jié))的大小,同時會放在內(nèi)存中最開始的位置,這個指針就是vptr(虛指針),它指向了vtbl(虛函數(shù)表),即 vptr內(nèi)容 vtbl的地址。
vtbl(虛函數(shù)表):
- vtbl 內(nèi)容:保存了一個類持有的虛函數(shù)的地址;
- 建兩個A對象,發(fā)現(xiàn)他們的虛函數(shù)指針相同,這說明他們的虛函數(shù)表屬于類,不屬于對象。所以虛函數(shù)表應(yīng)該存在共有區(qū);
- 位置:虛函數(shù)表放在了全局?jǐn)?shù)據(jù)段。
查找過程:
- 在編譯時,編譯器會為【整個繼承關(guān)系中的每個虛函數(shù)】進(jìn)行順序編號,按照這個編號順序,在vtbl中放置虛函數(shù)地址;
- 調(diào)用一個實(shí)例化對象的虛函數(shù)過程:
- 先找到vtptr(在實(shí)例化對象所在內(nèi)存的開頭位置);
- 通過vtptr內(nèi)容,找到vtbl;
- 從vtbl找到對應(yīng)虛函數(shù)的地址,把它當(dāng)成函數(shù)指針去調(diào)用;
- 函數(shù)指針調(diào)用的方式:后面的§,是傳遞隱藏參數(shù)this pointer;
4. 多態(tài)
- 多態(tài)和動態(tài)綁定是一回事(涉及虛函數(shù)、虛函數(shù)指針、虛函數(shù)表)
5. 圖示一
- 圖中有A、B、C三個對象:
- 對象關(guān)系:
- 對象內(nèi)容:
- A對象:2個虛函數(shù),2個非虛函數(shù),2個int數(shù)據(jù);
- B對象:
- 自身的內(nèi)容:1個非虛函數(shù),1個int;
- 繼承的內(nèi)容:繼承了A的2個虛函數(shù),但自己重新定義了其中一個;繼承了A的2個非虛函數(shù);繼承了A的兩個int數(shù)據(jù);
- 總內(nèi)容:2個虛函數(shù)(其中一個自定義),3個非虛函數(shù),3個int數(shù)據(jù);
- C對象:
- 自身的內(nèi)容:1個非虛函數(shù),2個int;
- 繼承的內(nèi)容:繼承了B的2個虛函數(shù),但自己重新定義了其中一個;繼承了B的3個非虛函數(shù);繼承了B的3個int數(shù)據(jù);
- 總內(nèi)容::2個虛函數(shù)(其中一個自定義),4個非虛函數(shù),5個int數(shù)據(jù);
- 三個類的函數(shù)個數(shù):
- 4個非虛函數(shù);
- 4個虛函數(shù);
6. 圖示二
- A為shape抽象類;
- B、C為具體的形狀類;
- A有draw虛函數(shù),B、C自定義了draw函數(shù)(相當(dāng)于上一頁的vfunc1());
- 右下角的容器:
- 使用父類指針指向子類的方式(多態(tài)),使容器可以包含多種類型;
7. template method補(bǔ)充
- 也可以使用基類指針指向派生類對象 CDocument* cdoc = new CMyDoc(),來調(diào)用OnFileOpen()函數(shù);
- 執(zhí)行Serialize()函數(shù),滿足動態(tài)綁定三個條件,編譯器會把Serialize()寫出函數(shù)指針調(diào)用的形式(圖左邊);
- 在動態(tài)綁定三個條件中的第二個,不太好理解:
- 指針是向上轉(zhuǎn)型后的指針(this指的是子類對象,符合向上轉(zhuǎn)型);
- 【簡單理解為只要this指的是子類對象,就滿足這個條件。】
- 可能右下角調(diào)用OnFileOpen()中的this指針類型是父類指針類型。(這樣就有父類指針指向子類對象)
12. const member functions(常量成員函數(shù))
1. 形式(const加的位置):
class Complex{
public:
// const member function(常量成員函數(shù))
double real () const { return resl; }
double imag () const { return im; }
private:
double re, im;
};
- 常量成員函數(shù)顧名思義:
- 只能定義在成員函數(shù)身上,全局函數(shù)不行;
2. member functions 與 object 的規(guī)則
- const object (要求 data members 不能改動);
- non-const object (data members 可改動);
- const member functions(保證這個成員函數(shù)不更改 data members);
- non-const member functions(不保證這個成員函數(shù)不更改 data members);
3. const member functions 和 non-const member functions 的特殊規(guī)則
13. 重載operator new、delete、 new[]、delete[]
1. 知識回顧
2. 重載 ::operator new、new[] 和 ::operator delete、delete[]
- 一般不重載全局operator new、delete、new[]、delete[];
3. 重載 member operator new 和 member operator delete
- 圖中的member operator delete中的optional參數(shù)表示該參數(shù)可選;
- 該類進(jìn)行new和delete中,優(yōu)先找member operator new 和 member operator delete;
4. 重載 member operator new[] 和 member operator delete[]
- 圖中的optional指該參數(shù)可選;
- 該類進(jìn)行new[] 和delete[]中,優(yōu)先找member operator new[] 和 member operator delete[];
5. operator new、delete、 new[]、delete[] 使用示范
1. member operator new、delete、 new[]、delete[]重載寫法
2. member operator new、delete、 new[]、delete[]調(diào)用過程
不帶有虛函數(shù)的類:
由上一頁可知,sizeof(Foo) = 12【int:4個字節(jié),long:4個字節(jié),string:4個字節(jié)(指針)】;
調(diào)用 operator new 和 delete:
調(diào)用 operator new[] 和 delete[]:
new[] 和 delete[] 調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的順序相反【看this指針順序】
帶有虛函數(shù)的類:
- 唯一不同在于,帶有虛函數(shù)的類,會多一個虛函數(shù)指針的大小;
- sizeof(Foo) = 16;
- 分配5個的大小 == 16*5 + 4 = 84;
3. 顯式調(diào)用global operator new、delete、 new[]、delete[]過程
- 強(qiáng)迫使用global version,沒有member version的打印信息;
14. 重載member operator new(…) 、 delete(…)
1. new(…) 、delete(…)和new、delete的區(qū)別
- 括號的意義:operator new() 、delete() 額外設(shè)置了參數(shù);
- placement術(shù)語介紹:
- member operator new() == placement new;
- member operator delete() == placement delete;
2. member operator new(…)
member operator new() 可以有多個參數(shù),但第一個參數(shù)類型一定是size_t(unsigned int),并且這個參數(shù)是由編譯器傳遞;
不同版本的 member operator new() 必須有不同的參數(shù)列(才能進(jìn)行函數(shù)重載,函數(shù)簽名不同):
- 即第一個參數(shù)之后的參數(shù),個數(shù)、類型要有區(qū)別;
member operator new() 調(diào)用方式:
調(diào)用時,需要手動傳遞的參數(shù)是第一個參數(shù)以后的參數(shù);
下面的 member operator new() 說明,定義時有三個參數(shù);
// 調(diào)用 operator new() 和 delete
// new(300, 'c'):說明這個operator new()有三個參數(shù),第一個參數(shù)不需要手動傳遞。
Foo* p = new(300, 'c') Foo(7); // 注意傳遞new的參數(shù),以及構(gòu)造參數(shù)的位置
delete p;
3. member operator delete(…)
- member operator delete() 也可以重載,也可以不重載;
- 這一步不是必須的,因?yàn)椴粫籨elete調(diào)用【正常 delete 調(diào)用 void operator delete(void*, size_t) 版本】;
- member operator delete() 調(diào)用:
- 無論new調(diào)用的是哪種版本,只有一般版本的delete會被調(diào)用;
- member operator delete() 作用:
- new操作分為三步:
- operator new;
- 轉(zhuǎn)型;
- 構(gòu)造函數(shù);
- 只有當(dāng) new 中第三步,調(diào)用的構(gòu)造函數(shù)拋出異常,才會調(diào)用這些 member operator new() 版本對應(yīng)的 operator delete() ,釋放之前 member operator new() 分配的空間;
- 它只可能這樣被調(diào)用,主要用來歸還未能完全創(chuàng)建成功的對象所占用的內(nèi)存空間。
4. member operator new(…)、delete(…)重載書寫和使用
5. 標(biāo)準(zhǔn)庫string重載placement new
- 重載 placement new 用于分配額外的空間,作為 string 的內(nèi)容空間;
- Rep:是標(biāo)準(zhǔn)庫 string 用于計(jì)數(shù)有多少用戶共用這個字符串對象的計(jì)數(shù)器(reference counting 技術(shù));
- reference counting 技術(shù):
- 允許多個擁有共同值的對象共享同一個對象實(shí)體,解決了同一個對象存在多分拷貝的問題。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
當(dāng)前標(biāo)題:C++面向?qū)ο缶幊蹋ㄏ拢?創(chuàng)新互聯(lián)
本文地址:
http://weahome.cn/article/ejjdc.html