bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

C++面向對象編程(下)-創新互聯

文章目錄
    • C++面向對象編程(下)
      • 11. vtpr(virtual pointer)和vtbl(virtual table)
        • 1. 前提須知
        • 2. 靜態綁定和動態綁定
        • 3. vtpr和vtbl
        • 4. 多態
        • 5. 圖示一
        • 6. 圖示二
        • 7. template method補充
      • 12. const member functions(常量成員函數)
        • 1. 形式(const加的位置):
        • 2. member functions 與 object 的規則
        • 3. const member functions 和 non-const member functions 的特殊規則
      • 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[]調用過程
          • 3. 顯式調用global operator new、delete、 new[]、delete[]過程
      • 14. 重載member operator new(...) 、 delete(...)
        • 1. new(...) 、delete(...)和new、delete的區別
        • 2. member operator new(...)
        • 3. member operator delete(...)
        • 4. member operator new(...)、delete(...)重載書寫和使用
        • 5. 標準庫string重載placement new

網站建設公司,為您提供網站建設,網站制作,網頁設計及定制網站建設服務,專注于成都定制網頁設計,高端網頁制作,對戶外休閑椅等多個行業擁有豐富的網站建設經驗的網站建設公司。專業網站設計,網站優化推廣哪家好,專業seo優化排名優化,H5建站,響應式網站。C++面向對象編程(下) 11. vtpr(virtual pointer)和vtbl(virtual table) 1. 前提須知
  • 實例對象在內存的表現:
    • 函數在內存中的位置,與實例對象占用的內存沒有關系;
    • 對于一個類的多個對象,函數在內存中也只會有一份
    • 實例對象占用的內存,只會包含對象的數據;如果有虛函數,還會包含一個虛指針;【無論有多少個虛函數,都只會多占用一個指針的空間;】
  • 繼承:
    • 對于父類中的函數,子類只是繼承了函數的調用權,不會為子類在內存中另外生成一份函數【因為函數始終只在內存占一份】;
    • 如果父類有虛函數,那么子類也一定有虛函數(繼承);
    • 雖然父類和子類中的非虛函數和數據,命名可以重復(因為二者沒有什么關系),但這樣的命名風格不好。
2. 靜態綁定和動態綁定
  • 類型:
    • 靜態類型:對象在聲明時采用的類型,在編譯期既已確定;
    • 動態類型:通常是指一個指針或引用目前所指對象的類型,是在運行期決定的;
  • 綁定(Binding):是指將變量和函數名轉換為地址的過程。
    • 靜態綁定:綁定的是靜態類型,所對應的函數或屬性依賴于對象的靜態類型,發生在編譯期;
      • 意味著綁定的函數或者變量,已經在編譯階段,該語句已經被編譯成“call 函數地址”或"callq 函數地址"這樣的匯編指令格式,并且這些匯編指令中的函數地址在程序編譯后是固定不變的,請記住,所有函數都有唯一的地址。
    • 動態綁定:綁定的是動態類型,所對應的函數或屬性依賴于對象的動態類型,發生在運行期;
  • 只有虛函數才使用的是動態綁定(實現多態),其他的全部是靜態綁定;
  • 編譯器使用動態綁定的三個條件:
    • 通過指針 / 引用調用函數;
    • 指針是向上轉型后的指針(this指的是子類對象,符合向上轉型);【即父類指針指向子類對象】
    • 指針調用的是虛函數。
    • 簡單一句話使用基類的引用(指針)調用虛函數

3. vtpr和vtbl
  • vtpr(虛指針):

    • 對于有virtual函數的類,它的實例化對象在內存空間中除了包含數據的大小,還會多出一個指針(4個字節)的大小,同時會放在內存中最開始的位置,這個指針就是vptr(虛指針),它指向了vtbl(虛函數表),即 vptr內容 vtbl的地址。
  • vtbl(虛函數表):

    • vtbl 內容:保存了一個類持有的虛函數的地址;
    • 建兩個A對象,發現他們的虛函數指針相同,這說明他們的虛函數表屬于類,不屬于對象。所以虛函數表應該存在共有區;
    • 位置:虛函數表放在了全局數據段。
  • 查找過程:

    • 在編譯時,編譯器會為【整個繼承關系中的每個虛函數】進行順序編號,按照這個編號順序,在vtbl中放置虛函數地址;
    • 調用一個實例化對象的虛函數過程:
      • 先找到vtptr(在實例化對象所在內存的開頭位置);
      • 通過vtptr內容,找到vtbl;
      • 從vtbl找到對應虛函數的地址,把它當成函數指針去調用
      • 函數指針調用的方式:后面的§,是傳遞隱藏參數this pointer;
        在這里插入圖片描述
4. 多態
  • 多態和動態綁定是一回事(涉及虛函數、虛函數指針、虛函數表)

5. 圖示一
  • 圖中有A、B、C三個對象:
    • 對象關系:
      • B是A的子類,C是B的子類;
    • 對象內容:
      • A對象:2個虛函數,2個非虛函數,2個int數據;
      • B對象:
        • 自身的內容:1個非虛函數,1個int;
        • 繼承的內容:繼承了A的2個虛函數,但自己重新定義了其中一個;繼承了A的2個非虛函數;繼承了A的兩個int數據;
        • 總內容:2個虛函數(其中一個自定義),3個非虛函數,3個int數據;
      • C對象:
        • 自身的內容:1個非虛函數,2個int;
        • 繼承的內容:繼承了B的2個虛函數,但自己重新定義了其中一個;繼承了B的3個非虛函數;繼承了B的3個int數據;
        • 總內容::2個虛函數(其中一個自定義),4個非虛函數,5個int數據;
    • 三個類的函數個數:
      • 4個非虛函數;
      • 4個虛函數;
        在這里插入圖片描述
6. 圖示二
  • A為shape抽象類;
  • B、C為具體的形狀類;
  • A有draw虛函數,B、C自定義了draw函數(相當于上一頁的vfunc1());
  • 右下角的容器:
    • 使用父類指針指向子類的方式(多態),使容器可以包含多種類型;
      在這里插入圖片描述

7. template method補充
  • 也可以使用基類指針指向派生類對象 CDocument* cdoc = new CMyDoc(),來調用OnFileOpen()函數;
  • 執行Serialize()函數,滿足動態綁定三個條件,編譯器會把Serialize()寫出函數指針調用的形式(圖左邊);
  • 在動態綁定三個條件中的第二個,不太好理解:
    • 指針是向上轉型后的指針(this指的是子類對象,符合向上轉型);
    • 【簡單理解為只要this指的是子類對象,就滿足這個條件。】
    • 可能右下角調用OnFileOpen()中的this指針類型是父類指針類型。(這樣就有父類指針指向子類對象)
      在這里插入圖片描述

12. const member functions(常量成員函數) 1. 形式(const加的位置):
class Complex{
public:
    // const member function(常量成員函數)
	double real () const { return resl; }
	double imag () const { return im; }
private:
	double re, im;
};
  • 常量成員函數顧名思義:
    • 只能定義在成員函數身上,全局函數不行;
2. member functions 與 object 的規則
  • const object (要求 data members 不能改動);
  • non-const object (data members 可改動);
  • const member functions(保證這個成員函數不更改 data members);
  • non-const member functions(不保證這個成員函數不更改 data members);
    在這里插入圖片描述
3. const member functions 和 non-const member functions 的特殊規則
  • 一個 member function 如果同時存在 const 和 non-const 版本:

    • 明確了調用函數的對象是 const object,還是 non-const object;
    • 主要是明確了調用 const member functions 的對象(因為一般情況下,non-const object也可以調用const member functions,上面表的第一行)
      在這里插入圖片描述
  • 標準庫(string)的成員函數示范:

    • operator[] 函數同時存在 const 和 non-const 版本;
    • 常量成員函數的const是函數簽名的一部分,所以可以進行函數重載;
    • 根據特殊規則:
      • 調用 const member functions 的對象,一定是const object;
      • 調用 non-const member functions 的對象,一定是non-const object;
        在這里插入圖片描述

13. 重載operator new、delete、 new[]、delete[] 1. 知識回顧
  • new過程(分三步):

    • 先使用operator new分配空間,底層使用malloc函數;
    • 進行指針類型轉換;
    • 再調用構造函數:對于帶有指針的類,通過構造函數,分配指針指向的數據;
  • delete過程(分兩步):

    • 先調用析構函數:對于帶有指針的類,通過析構函數,釋放指針指向的數據;
    • 再使用operator delete釋放分配的空間,底層使用free函數。
  • 在new和delete的過程中,new和delete本身是不能重載的,但new和delete中operator new和operator delete操作是可以重載的:

    • operator new和operator delete的調用順序
      • 先找類中的重載版本;
      • 再找全局版本。
2. 重載 ::operator new、new[] 和 ::operator delete、delete[]
  • 一般不重載全局operator new、delete、new[]、delete[];
    在這里插入圖片描述
3. 重載 member operator new 和 member operator delete
  • 圖中的member operator delete中的optional參數表示該參數可選;
  • 該類進行new和delete中,優先找member operator new 和 member operator delete
    在這里插入圖片描述
4. 重載 member operator new[] 和 member operator delete[]
  • 圖中的optional指該參數可選;
  • 該類進行new[] 和delete[]中,優先找member operator new[] 和 member operator delete[];
    在這里插入圖片描述
5. operator new、delete、 new[]、delete[] 使用示范 1. member operator new、delete、 new[]、delete[]重載寫法
  • (僅僅增加打印信息)

  • 重載函數:

    • operator new;
    • operator delete;
    • operator new[];
    • operator delete[];
  • global 與member operator new、delete、 new[]、delete[]相關函數的調用順序

    • // 優先調用member version,如果沒有member version,就調用global version;
      Foo* pf = new Foo;
      delete pf;
    • // 強制調用global version;
      Foo* pf = ::new Foo;
      ::delete pf;

在這里插入圖片描述

2. member operator new、delete、 new[]、delete[]調用過程
  • 不帶有虛函數的類:

    • 由上一頁可知,sizeof(Foo) = 12【int:4個字節,long:4個字節,string:4個字節(指針)】;

    • 調用 operator new 和 delete:

      • // 調用 operator new 和 delete
        Foo* p = new Foo(7);	// 這個參數是構造函數的參數
        delete p;
      • 分配一個對象的大小空間(這個例子 == 12);

      • 注意點:

        • operator new的第一個參數是編譯器自動傳遞的;
        • 下圖左邊①中后面的Foo(7)是Foo的構造函數,不要和new的參數混淆了;

    • 調用 operator new[] 和 delete[]:

      • // 調用 operator new[] 和 delete[]
        Foo* pArray = new Foo[5];
        delete pArray[];
      • 分配5個對象的大小空間 == 12*5 + 4 == 64;【調用operator new[] 時,會有一個額外整型用于記錄數組的大小,整型4個字節,面向對象part one中有講過】

    • new[] 和 delete[] 調用構造函數和析構函數的順序相反【看this指針順序】


  • 帶有虛函數的類:

    • 唯一不同在于,帶有虛函數的類,會多一個虛函數指針的大小
    • sizeof(Foo) = 16
    • 分配5個的大小 == 16*5 + 4 = 84;
      在這里插入圖片描述
3. 顯式調用global operator new、delete、 new[]、delete[]過程
  • 強迫使用global version,沒有member version的打印信息;
    在這里插入圖片描述
14. 重載member operator new(…) 、 delete(…) 1. new(…) 、delete(…)和new、delete的區別
  • 括號的意義:operator new() 、delete() 額外設置了參數;
  • placement術語介紹:
    • member operator new() == placement new;
    • member operator delete() == placement delete;
2. member operator new(…)
  • member operator new() 可以有多個參數,但第一個參數類型一定是size_t(unsigned int),并且這個參數是由編譯器傳遞;

  • 不同版本的 member operator new() 必須有不同的參數列(才能進行函數重載,函數簽名不同):

    • 即第一個參數之后的參數,個數、類型要有區別;
  • member operator new() 調用方式:

    • 調用時,需要手動傳遞的參數是第一個參數以后的參數;

    • 下面的 member operator new() 說明,定義時有三個參數;

    • // 調用 operator new() 和 delete
      // new(300, 'c'):說明這個operator new()有三個參數,第一個參數不需要手動傳遞。
      Foo* p = new(300, 'c') Foo(7);	// 注意傳遞new的參數,以及構造參數的位置
      delete p;
3. member operator delete(…)
  • member operator delete() 也可以重載,也可以不重載;
  • 這一步不是必須的,因為不會被delete調用【正常 delete 調用 void operator delete(void*, size_t) 版本】;
  • member operator delete() 調用:
    • 無論new調用的是哪種版本,只有一般版本的delete會被調用;
  • member operator delete() 作用:
    • new操作分為三步:
      • operator new;
      • 轉型;
      • 構造函數;
    • 只有當 new 中第三步,調用的構造函數拋出異常,才會調用這些 member operator new() 版本對應的 operator delete() ,釋放之前 member operator new() 分配的空間;
    • 它只可能這樣被調用,主要用來歸還未能完全創建成功的對象所占用的內存空間。
      在這里插入圖片描述
4. member operator new(…)、delete(…)重載書寫和使用
  • member operator new():

    • (1) ~ (4) 不同版本的 placement new;
    • (5):故意寫錯第一參數的 placement new 不合法版本;編譯器會報錯,要求第一個參數類型是 size_t;
      在這里插入圖片描述
  • member operator delete():

    • (1) ~ (4) 的 placement delete 對應上一頁不同版本的 placement new;
    • 【上一頁在構造函數中故意拋出異常;】
    • 右邊⑤:構造函數失敗(拋出異常),是否會調用對應的 placement delete,取決于編譯器;
    • 最下面的方框:
      • 沒有定義對應 operator new(…) 版本的 operator delete(…),也不會報錯;
      • 這意味著放棄構造函數拋出的異常。
        在這里插入圖片描述
5. 標準庫string重載placement new
  • 重載 placement new 用于分配額外的空間,作為 string 的內容空間;
  • Rep:是標準庫 string 用于計數有多少用戶共用這個字符串對象的計數器(reference counting 技術);
  • reference counting 技術:
    • 允許多個擁有共同值的對象共享同一個對象實體,解決了同一個對象存在多分拷貝的問題。
      在這里插入圖片描述

你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧

當前文章:C++面向對象編程(下)-創新互聯
文章出自:http://vcdvsql.cn/article12/ejjdc.html

成都網站建設公司_創新互聯,為您提供做網站定制開發云服務器定制網站網站收錄面包屑導航

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網站建設