中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

北京家裝設計師排名北京網站優(yōu)化推廣方案

北京家裝設計師排名,北京網站優(yōu)化推廣方案,學年論文網站建設,使用二級域名會影響網站收錄💓博主CSDN主頁:杭電碼農-NEO💓 ? ?專欄分類:C從入門到精通? ? 🚚代碼倉庫:NEO的學習日記🚚 ? 🌹關注我🫵帶你學習C ? 🔝🔝 多態(tài) 1. 前言2. 多態(tài)的概念以及定義3. 多態(tài)的實…

💓博主CSDN主頁:杭電碼農-NEO💓
?
?專欄分類:C++從入門到精通?
?
🚚代碼倉庫:NEO的學習日記🚚
?
🌹關注我🫵帶你學習C++
? 🔝🔝


在這里插入圖片描述


多態(tài)

  • 1. 前言
  • 2. 多態(tài)的概念以及定義
  • 3. 多態(tài)的實例調用情況
  • 4. 構成多態(tài)的兩個特例
  • 5. 多態(tài)的底層原理分析(一)
  • 6. 多態(tài)底層原理分析(二)
  • 7. 多態(tài)中的兩個關鍵字
  • 8. 抽象類以及虛函數的幾個結論
  • 9. 總結以及拓展

1. 前言

繼承和多態(tài)這兩兄弟常常一起出現(xiàn)
繼承是實現(xiàn)多態(tài)的前提!

本章重點:

本篇文章著重講解多態(tài)的概念以及
定義,多態(tài)的底層原理和析構函數重寫
以及函數重寫的兩個例外條件
多繼承中的虛函數表關系.其中,簡單介紹
的部分有抽象類的概念以及定義和
繼承與多態(tài)中的兩個新增關鍵字

注:如果你不知道什么是繼承,或繼承
的知識掌握不牢固,請先閱讀下面文章:

C++繼承深度剖析


2. 多態(tài)的概念以及定義

概念: 通俗來說,多態(tài)就是多種狀態(tài)
父子對象完成相同任務會產生不同的結果

比如:
學生和普通人都去買門票
學生是半價,而普通人是全價

在繼承中構成多態(tài)要有兩個條件:

  1. 必須通過基類的指針或引用調用虛函數
  2. 被調用的函數必須是虛函數
    并且子類的虛函數要被重寫

現(xiàn)在的你可能有一萬個問號
什么是虛函數?什么是重寫?
沒關系,我們一步一步講!

關鍵字virtual加在成員函數前
這個成員函數就是虛函數!

在這里插入圖片描述
虛函數的重寫(也叫覆蓋):

派生類中有一個跟基類完全相同的虛函數(即派生類虛函數與基類虛函數的,返回值類型、函數名字、參數列表完全相同),稱子類的虛函數重寫了基類的虛函數

class Person {
public:virtual void BuyTicket() { cout << "買票-全價" << endl; }
};
class Student : public Person {
public:virtual void BuyTicket() { cout << "買票-半價" << endl; }
};

上面的代碼中,BuyTicket函數就被重寫了!

概念講完,下一步進行實戰(zhàn)!


3. 多態(tài)的實例調用情況

構成多態(tài)的條件就兩個,一定要熟記!
一定要熟記!一定要熟記!重要的事情說三遍

下面是多態(tài)的實例:

class Person {
public:virtual void BuyTicket() { cout << "買票-全價" << endl; }
};
class Student : public Person {
public:virtual void BuyTicket() { cout << "買票-半價" << endl; }
};int main()
{Person* p1 = new Person;Person* p2 = new Student;p1->BuyTicket();p2->BuyTicket();return 0;
}

我們知道一個事實:
基類的指針或引用可以指向/引用
子類的對象,我們稱為切片

p1和p2是基類指針,它們調用的
函數恰好還被重寫了,所以這里符合
多態(tài),p1指針指向的內容是Person
所以它調用Person中的函數,然而p2
指針指向的內容是Student,所以它
調用的是Student中的函數!

依次打印:"買票-全家","買票-半價"


4. 構成多態(tài)的兩個特例

  1. 特例一: 子類的虛函數不寫virtual
    依舊構成多態(tài)
class Person {
public:virtual void BuyTicket() { cout << "買票-全價" << endl; }
};
class Student : public Person {
public:void BuyTicket() { cout << "買票-半價" << endl; }
};
Person* p1 = new Person;
Person* p2 = new Student;
p1->BuyTicket();
p2->BuyTicket();

這樣寫也是構成多態(tài)的!

  1. 特例二:基類與派生類虛函數返回值類型不同
    也可以構成多態(tài)(返回值必須滿足某種條件)
class A{};
class B : public A {};class Person {
public:virtual A* f() {return new A;}
};
class Student : public Person {
public:virtual B* f() {return new B;}
};

父類的返回值要返回父類
子類的返回值要返回子類

  1. 注意事項1:父類不寫virtual,而子類的同名
    函數寫了virtual,這是不構成多態(tài)的!
class Person {
public:void BuyTicket() { cout << "買票-全價" << endl; }
};
class Student : public Person {
public:virtual void BuyTicket() { cout << "買票-半價" << endl; }
};

不構成多態(tài)!

  1. 注意事項2:在繼承體系中,父子類的同名
    函數不構成重寫就構成隱藏,不可能構成重載!

5. 多態(tài)的底層原理分析(一)

在這里插入圖片描述

如果你單純的認為Base類只有一個
整型變量占用空間的話,那你就上當啦!
事實上在32位機器下,這里的結果是8
在64位機器下,這里的結果是16!

這是因為它除了有一個變量外,還有
一個指針,此指針指向一個虛函數表

我們通過以下的代碼來觀察內存:

class A
{
public:virtual void func1(){cout << "父類func1";}
private:int _a;
};
class B : public A
{
public:virtual void func1(){cout << "子類func1";}
private:int _b;
};int main()
{A a;B b;return 0;
}

在這里插入圖片描述

此指針叫虛表指針:vfptr,也就是
virtual function ptr

這個指針并不是直接指向虛函數的地址
而是指向一個虛函數表,可以理解位一個
數組,此數組中存放著此對象中所有的虛
函數的地址,它們的關系可以用下圖表示:

在這里插入圖片描述

注:不管有沒有繼承體系或多態(tài)
只要有虛函數就有虛表!


6. 多態(tài)底層原理分析(二)

現(xiàn)在得出一個結論:有虛函數的
類對象中還存放了一個虛表指針!

那么父類和子類的虛表指針和指向
的內容有什么不同或相同處嗎?
形成多態(tài)現(xiàn)象的原理又是什么?
我來一一解答這些問題:

  1. 通過下面的代碼來觀察內存情況
    得出父子類虛表的關聯(lián):
class A
{
public:virtual void func1()cout << "父類func1";virtual void func2()cout << "父類func2";
private:int _a;
};
class B : public A
{
public:virtual void func1()cout << "子類func1";
private:int _b;
};
int main()
{A a;B b;return 0;
}

請看下圖觀察情況:

在這里插入圖片描述

結論:

父類和子類的虛表指針是不同的
證明父子類各有一張?zhí)摵瘮当?
函數func1在子類中被重寫了,所以
父子類虛表中的func1函數地址是不同的
函數func2沒有被子類重寫,所以
父子類虛表中的func2函數地址是相同的

拓展結論:同一個類的不同對象共用一個虛表

  1. 多態(tài)的原理深度剖析:

當一個函數A被重寫時,它的父類虛表存放
父類函數A的地址,子類虛表存放的是子類
函數A的地址!

當父類的指針或引用指向子類空間時
調用虛函數時,會到指向對象的虛表中
中找到對應的虛函數地址,進行調用!

拓展結論: 父子類都只有A函數或無函數時

  1. 若父類寫了虛函數A,而子類
    甚至沒有寫函數A,此時子類對象中
    存儲的虛函數地址與父類相同

  2. 若父類甚至沒有寫函數A,而子類
    直接寫了虛函數A,則父類對象中沒有
    虛表,而子類對象中有虛表(存放A)


7. 多態(tài)中的兩個關鍵字

  1. final:修飾虛函數,表示該虛函數不能被重寫

在這里插入圖片描述

  1. override:檢查子類類虛函數是否重寫了
    基類虛函數如果沒有重寫編譯報錯

在這里插入圖片描述


8. 抽象類以及虛函數的幾個結論

抽象類概念:

在虛函數的后面寫上 =0 ,則這個函數為純虛函數。包含純虛函數的類叫做抽象類(也叫接口類),抽象類不能實例化出對象。派生類繼承后也不能實例化出對象,只有重寫純虛函數,派生類才能實例化出對象。純虛函數規(guī)范了派生類必須重寫

抽象類的只需了解概念,實際中
使用到的場景很少

關于虛函數的幾個小結論:

  1. 析構函數最好定義為虛函數
  2. 構造函數不能定義為虛函數
  3. 靜態(tài)成員函數不能是虛函數
  4. 內聯(lián)函數(inline)不能是虛函數

為什么說析構函數最好定義為虛函數?
請看下面的例子:

class Person {
public:virtual ~Person() {cout << "~Person()" << endl;}
};
class Student : public Person {
public:virtual ~Student() { cout << "~Student()" << endl; }
};
// 只有派生類Student的析構函數重寫了Person的析構函數
//下面的delete對象調用析構函數,才能構成多態(tài)
//才能保證p1和p2指向的對象正確的調用析構函數。
int main()
{Person* p1 = new Person;Person* p2 = new Student;delete p1;delete p2;return 0;
}

若析構函數不是虛函數,delete ptr2時
不符合多態(tài),ptr2是Person類型指針
就只會調用Person類的析構,會有問題

若析構函數是虛函數,delete ptr2時
構成多態(tài)的條件,指針指向父類的對象
就調用父類的析構,指向子類的對象
就調用子類的析構,這樣才是正確的!


9. 總結以及拓展

多態(tài)在校招的筆試面試中考察的
非常之多,很多面試官都喜歡在這
上面考察學生的掌握C++語法的程度
所以同學們請耐心學習!

拓展閱讀:

多繼承場景下的多態(tài)


🔎 下期預告:二叉搜索樹 🔍
http://www.risenshineclean.com/news/36872.html

相關文章:

  • 清溪仿做網站懂得網站推廣
  • 日本無碼做受網站企業(yè)seo顧問
  • 網站設計報價是多少錢廣告信息發(fā)布平臺
  • 蘇州網站設計哪家好韓國比分預測
  • 安卓做網站seo網站關鍵詞優(yōu)化報價
  • 鄭州好的網站設計公司營銷推廣活動策劃方案大全
  • 如何查詢網站關鍵詞密度濟南seo全網營銷
  • 廣州衛(wèi)健委疫情最新消息關鍵詞優(yōu)化的作用
  • 企業(yè)網站建設報價百度渠道開戶
  • 江陰做網站優(yōu)化百度官網登錄入口手機版
  • 京東購物商城網絡排名優(yōu)化軟件
  • asp.net做網站Dreamver百度搜圖匹配相似圖片
  • 化妝品網站設計報告怎么網上推廣自己的產品
  • 做好政府網站建設工作的通知安卓神級系統(tǒng)優(yōu)化工具
  • 模板式網站價格百度競價的優(yōu)勢和劣勢
  • 給平頂山公安局做網站的公司前端培訓哪個機構靠譜
  • 天元建設集團有限公司濟南第六建筑工程公司seo站長工具查詢系統(tǒng)
  • 公司做網站找誰做網站的公司seo推廣公司教程
  • 微信上登錄網站同步怎么做宣傳軟文是什么
  • 做網站的注意什么口碑最好的it培訓機構
  • 建立網站服務的公司網站武漢百度快速排名提升
  • 網站怎么做一盤優(yōu)化排名百度旗下13個app
  • 石家莊個人建網站長沙服務好的網絡營銷
  • 如何做網站后臺的維護互聯(lián)網推廣項目
  • 網站建設公司怎么找客戶天津推廣的平臺
  • 煙臺做網站那家好網絡營銷的缺點及建議
  • phpcms 怎么做視頻網站seo關鍵詞排名優(yōu)化軟件怎么選
  • 網上課程網站建設方案百度競價官網
  • 泰州網站建設報價合肥seo推廣外包
  • 網站設計一年費用有鏈接的網站