最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++三大核心特性之多態(tài)詳解

 更新時(shí)間:2025年11月07日 08:25:53   作者:zzh_zao  
多態(tài)是?個(gè)繼承關(guān)系的下的類對(duì)象,去調(diào)?同?函數(shù),產(chǎn)?了不同的?為,這篇文章主要介紹了C++三大核心特性之多態(tài)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

什么是多態(tài)?

多態(tài)(Polymorphism)是面向?qū)ο缶幊痰娜蠛诵奶匦灾唬ǚ庋b、繼承、多態(tài)),源于希臘語"多種形態(tài)"。在C++中,它允許我們使用統(tǒng)一的接口處理不同類型的對(duì)象,顯著提高了代碼的靈活性和可擴(kuò)展性。

核心概念

  1. 同一接口,多種形態(tài)
    不同的對(duì)象可以通過相同的方法名調(diào)用,但實(shí)際執(zhí)行的邏輯由對(duì)象自身的類決定。
  2. 解耦調(diào)用與實(shí)現(xiàn)
    調(diào)用者只需關(guān)注接口(方法名和參數(shù)),無需關(guān)心具體實(shí)現(xiàn),提高代碼的可擴(kuò)展性和可維護(hù)性。

多態(tài)的定義及實(shí)現(xiàn)

多態(tài)的構(gòu)成條件

多態(tài)是?個(gè)繼承關(guān)系的下的類對(duì)象,去調(diào)?同?函數(shù),產(chǎn)?了不同的?為。
實(shí)現(xiàn)多態(tài)還有兩個(gè)必須重要條件:

  1. 必須是基類的指針或者引?調(diào)?虛函數(shù)

  2. 被調(diào)?的函數(shù)必須是虛函數(shù),并且完成了虛函數(shù)重寫/覆蓋。說明:要實(shí)現(xiàn)多態(tài)效果,第?必須是基類的指針或引?,因?yàn)橹挥谢惖闹羔樆蛞?才能既指向基類 對(duì)象?指向派?類對(duì)象;第?派?類必須對(duì)基類的虛函數(shù)完成重寫/覆蓋,重寫或者覆蓋了,基類和派 ?類之間才能有不同的函數(shù),多態(tài)的不同形態(tài)效果才能達(dá)到。

虛函數(shù)

類成員函數(shù)前?加virtual修飾,那么這個(gè)成員函數(shù)被稱為虛函數(shù)。注意?成員函數(shù)不能加virtual修飾。

class A
{

public:
 virtual void() {}
};

虛函數(shù)的重寫/覆蓋

虛函數(shù)的重寫/覆蓋:派?類中有?個(gè)跟基類完全相同的虛函數(shù)(即派?類虛函數(shù)與基類虛函數(shù)的返回值類型、函數(shù)名字、參數(shù)列表完全相同),稱派?類的虛函數(shù)重寫了基類的虛函數(shù)。

注意:在重寫基類虛函數(shù)時(shí),派?類的虛函數(shù)在不加virtual關(guān)鍵字時(shí),也可以構(gòu)成重寫(因?yàn)槔^承后基類的虛函數(shù)被繼承下來了在派?類依舊保持虛函數(shù)屬性)

關(guān)鍵技術(shù)原理

  1. 虛函數(shù)表(vtable)

    • 每個(gè)包含虛函數(shù)的類自動(dòng)生成虛函數(shù)表
    • 存儲(chǔ)該類所有虛函數(shù)的地址
    • 創(chuàng)建對(duì)象時(shí)隱式添加vptr指針指向vtable
  2. 動(dòng)態(tài)綁定過程

最佳實(shí)踐指南

  1. 使用override關(guān)鍵字明確重寫意圖

  2. 基類析構(gòu)函數(shù)必須聲明為virtual

  3. 接口類使用純虛函數(shù)

  4. 性能考量:虛函數(shù)調(diào)用比普通函數(shù)多一次指針解引用

虛函數(shù)重寫

協(xié)變

派?類重寫基類虛函數(shù)時(shí),與基類虛函數(shù)返回值類型不同。即基類虛函數(shù)返回基類對(duì)象的指針或者引?,派?類虛函數(shù)返回派?類對(duì)象的指針或者引?時(shí),稱為協(xié)變。核心概念

  1. 基類虛函數(shù)返回基類類型指針 / 引用。
  2. 派生類重寫函數(shù)返回派生類類型指針 / 引用。
  3. 編譯器會(huì)自動(dòng)處理類型轉(zhuǎn)換,確保調(diào)用的一致性。

協(xié)變的條件

  1. 基類函數(shù)必須為虛函數(shù)。
  2. 返回類型必須是指針或引用(不能是值類型)。
  3. 派生類返回類型必須是基類返回類型的公有派生類。
  4. 函數(shù)簽名的其他部分(參數(shù)、常量性)必須完全相同。

析構(gòu)函數(shù)的重寫

基類的析構(gòu)函數(shù)為虛函數(shù),此時(shí)派?類析構(gòu)函數(shù)只要定義,?論是否加virtual關(guān)鍵字,都與基類的析構(gòu)函數(shù)構(gòu)成重寫,雖然基類與派?類析構(gòu)函數(shù)名字不同看起來不符合重寫的規(guī)則,實(shí)際上編譯器對(duì)析構(gòu)函數(shù)的名稱做了特殊處理,編譯后析構(gòu)函數(shù)的名稱統(tǒng)?處理成destructor,所以基類的析構(gòu)函數(shù)加了vialtual修飾,派?類的析構(gòu)函數(shù)就構(gòu)成重寫。

class A

{

public:
 virtual ~A()
 {
 cout << "~A()" << endl;
 }
};

class B : public A {

public:
 ~B()
 { 
 cout << "~B()->delete:"<<_p<< endl;
 delete _p;
 }

protected:
 int* _p = new int[10];
};

int main()
{
 A* p1 = new A;
 A* p2 = new B;
 delete p1;
 delete p2;
 return 0;
}

如果~A(),不加virtual,那么delete p2時(shí)只調(diào)?的A的析構(gòu)函數(shù),沒有調(diào)?B的析構(gòu)函數(shù),就會(huì)導(dǎo)致內(nèi)存泄漏問題,因?yàn)?~B()中在釋放資源。

只有派?類Student的析構(gòu)函數(shù)重寫了Person的析構(gòu)函數(shù),下?的delete對(duì)象調(diào)?析構(gòu)函數(shù),才能構(gòu)成多態(tài),才能保證p1和p2指向的對(duì)象正確的調(diào)?析構(gòu)函數(shù)。

override和final關(guān)鍵字

  1. override 關(guān)鍵字
    作用
    明確標(biāo)記一個(gè)函數(shù)是重寫基類的虛函數(shù),編譯器會(huì)檢查以下條件:
    基類中是否存在同名虛函數(shù)。
    基類和派生類的函數(shù)簽名(參數(shù)、常量性、引用限定符)是否嚴(yán)格一致。
    返回類型是否符合協(xié)變規(guī)則(如果適用)。
  2. final 關(guān)鍵字
    作用
    final 有兩種用法:
    修飾虛函數(shù):禁止派生類重寫該虛函數(shù)。
    修飾類:禁止該類被繼承。

純虛函數(shù)和抽象類

在虛函數(shù)的后?寫上=0,則這個(gè)函數(shù)為純虛函數(shù),純虛函數(shù)不需要定義實(shí)現(xiàn)(實(shí)現(xiàn)沒啥意義因?yàn)橐慌?類重寫,但是語法上可以實(shí)現(xiàn)),只要聲明即可。包含純虛函數(shù)的類叫做抽象類,抽象類不能實(shí)例化出對(duì)象,如果派?類繼承后不重寫純虛函數(shù),那么派?類也是抽象類。純虛函數(shù)某種程度上強(qiáng)制了派?類重寫虛函數(shù),因?yàn)椴恢貙憣?shí)例化不出對(duì)象

  • 純虛函數(shù):在基類中聲明為virtual,并且沒有實(shí)現(xiàn)的函數(shù),形式為virtual void func() = 0;
  • 抽象類:包含純虛函數(shù)的類稱為抽象類,不能實(shí)例化對(duì)象,只能作為基類被派生。
  • 示例:
    class Shape {
    public:
        virtual void draw() = 0; // 純虛函數(shù)
    };
    
    class Circle : public Shape {
    public:
        void draw() override {
            cout << "Drawing Circle" << endl;
        }
    };
    
    • Shape是一個(gè)抽象類,Circle是派生類,重寫了draw()函數(shù)。
    • 多態(tài)的使用:
      Shape* shape = new Circle();
      shape->draw(); // 輸出:Drawing Circle
      

多態(tài)的原理

多態(tài)是如何實(shí)現(xiàn)的

在C++中,多態(tài)主要通過虛函數(shù)(virtual functions)和繼承機(jī)制來實(shí)現(xiàn)。以下是多態(tài)實(shí)現(xiàn)的詳細(xì)過程和原理:

1. 虛函數(shù)表(vtable)

  • 概念:每個(gè)包含虛函數(shù)的類都會(huì)有一個(gè)虛函數(shù)表(vtable),它是一個(gè)存儲(chǔ)虛函數(shù)地址的數(shù)組。當(dāng)創(chuàng)建一個(gè)類的對(duì)象時(shí),對(duì)象會(huì)包含一個(gè)指向其類的虛函數(shù)表的指針(vptr)。
  • 作用:vtable是實(shí)現(xiàn)多態(tài)的關(guān)鍵。當(dāng)通過基類指針或引用調(diào)用虛函數(shù)時(shí),程序會(huì)通過vptr找到對(duì)應(yīng)的vtable,然后通過vtable找到實(shí)際的虛函數(shù)地址。

虛函數(shù)表知識(shí)要點(diǎn)

  1. 基類對(duì)象的虛函數(shù)表中存放基類所有虛函數(shù)的地址。同類型的對(duì)象共?同?張?zhí)摫?,不同類型的?duì)象各?有獨(dú)?的虛表,所以基類和派?類有各?獨(dú)?的虛表。
  2. 派?類由兩部分構(gòu)成,繼承下來的基類和??的成員,?般情況下,繼承下來的基類中有虛函數(shù)表指針,??就不會(huì)再?成虛函數(shù)表指針。但是要注意的這?繼承下來的基類部分虛函數(shù)表指針和基類對(duì)象的虛函數(shù)表指針不是同?個(gè),就像基類對(duì)象的成員和派?對(duì)象中的基類對(duì)象成員也獨(dú)?的。
  3. 派?類中重寫的基類的虛函數(shù),派?類的虛函數(shù)表中對(duì)應(yīng)的虛函數(shù)就會(huì)被覆蓋成派?類重寫的虛函數(shù)地址。
  4. 派?類的虛函數(shù)表中包含,(1)基類的虛函數(shù)地址,(2)派?類重寫的虛函數(shù)地址完成覆蓋,派?類??的虛函數(shù)地址三個(gè)部分。
  5. 虛函數(shù)表本質(zhì)是?個(gè)存虛函數(shù)指針的指針數(shù)組,?般情況這個(gè)數(shù)組最后?放了?個(gè)0x00000000標(biāo)記。(此條取決于編譯器)
  6. 虛函數(shù)存儲(chǔ)的位置(vs下為常量區(qū))
    可以自行驗(yàn)證:
class Base {

public:
 virtual void func1() {}

protected:
 int a = 1;
};

class Derive : public Base
{
public:
 virtual void func1() {}
protected:
 int b = 2;
};

int main()
{
 int i = 0;
 static int j = 1;
 int* p1 = new int;
 const char* p2 = "xxxxxxxx";
 printf("棧:%p\n", &i);
 printf("靜態(tài)區(qū):%p\n", &j);
 printf("堆:%p\n", p1);
 printf("常量區(qū):%p\n", p2);
 Base b;
 Base* p3 = &b;
 printf("虛表地址:%p\n", *(int*)p3);
 return 0;
}
//通過比較虛表地址,找到其最近的內(nèi)存片段來確定

2. 虛函數(shù)的聲明

  • 在類中使用virtual關(guān)鍵字聲明函數(shù)為虛函數(shù)。
    Base為基類,Derived為繼承類。
    class Base {
    public:
        virtual void show() {
            cout << "Base show()" << endl;
        }
    };
    
    class Derived : public Base {
    public:
        void show() override { // override表示重寫基類的虛函數(shù)
            cout << "Derived show()" << endl;
        }
    };
    
    • Base類的show()函數(shù)被聲明為虛函數(shù),Derived類重寫了這個(gè)虛函數(shù)。

3. 多態(tài)的實(shí)現(xiàn)過程

  • 創(chuàng)建對(duì)象
    Derived d;
    
    • 當(dāng)創(chuàng)建Derived類的對(duì)象d時(shí),對(duì)象中會(huì)包含一個(gè)vptr,指向Derived類的vtable。
    • Derived類的vtable中存儲(chǔ)了Derived類重寫的虛函數(shù)show()的地址。
  • 通過基類指針或引用調(diào)用虛函數(shù)
    Base* ptr = &d;
    ptr->show();
    
    • ptr是一個(gè)指向Base類的指針,但它指向的是Derived類的對(duì)象。
    • 當(dāng)調(diào)用ptr->show()時(shí),程序會(huì)通過ptr找到對(duì)象的vptr,然后通過vptr找到Derived類的vtable,最終調(diào)用Derived類的show()函數(shù)。
    • 這就是多態(tài)的運(yùn)行時(shí)綁定(動(dòng)態(tài)綁定)過程。

動(dòng)態(tài)綁定與靜態(tài)綁定

• 對(duì)不滿?多態(tài)條件(指針或者引?+調(diào)?虛函數(shù))的函數(shù)調(diào)?是在編譯時(shí)綁定,也就是編譯時(shí)確定調(diào)?函數(shù)的地址,叫做靜態(tài)綁定。

• 滿?多態(tài)條件的函數(shù)調(diào)?是在運(yùn)?時(shí)綁定,也就是在運(yùn)?時(shí)到指向?qū)ο蟮奶摵瘮?shù)表中找到調(diào)?函數(shù)的地址,也就做動(dòng)態(tài)綁定。

總結(jié)

到此這篇關(guān)于C++三大核心特性之多態(tài)詳解的文章就介紹到這了,更多相關(guān)C++多態(tài)詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)統(tǒng)計(jì)代碼運(yùn)行時(shí)間的示例詳解

    C++實(shí)現(xiàn)統(tǒng)計(jì)代碼運(yùn)行時(shí)間的示例詳解

    這篇文章主要為大家詳細(xì)介紹了C++一個(gè)有趣的小項(xiàng)目——統(tǒng)計(jì)代碼運(yùn)行時(shí)間,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-05-05
  • C/C++實(shí)現(xiàn)對(duì)STORM運(yùn)行信息查看及控制的方法

    C/C++實(shí)現(xiàn)對(duì)STORM運(yùn)行信息查看及控制的方法

    這篇文章主要介紹了C/C++實(shí)現(xiàn)對(duì)STORM運(yùn)行信息查看及控制的方法,需要的朋友可以參考下
    2014-07-07
  • 手把手帶你了解C++最小棧

    手把手帶你了解C++最小棧

    這篇文章主要介紹了C++的最小棧,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • c++中l(wèi)og4cplus日志庫使用的基本步驟和示例代碼

    c++中l(wèi)og4cplus日志庫使用的基本步驟和示例代碼

    這篇文章主要給大家介紹了關(guān)于c++中l(wèi)og4cplus日志庫使用的相關(guān)資料,log4cplus是一款開源的c++日志庫,具有線程安全,靈活,以及多粒度控制的特點(diǎn),log4cplus可以將日志按照優(yōu)先級(jí)進(jìn)行劃分,使其可以面向程序的調(diào)試,運(yùn)行,測(cè)試,后期維護(hù)等軟件全生命周期,需要的朋友可以參考下
    2024-06-06
  • C語言實(shí)現(xiàn)順序循環(huán)隊(duì)列實(shí)例

    C語言實(shí)現(xiàn)順序循環(huán)隊(duì)列實(shí)例

    大家好,本篇文章主要講的是C語言實(shí)現(xiàn)順序循環(huán)隊(duì)列實(shí)例,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • C語言實(shí)現(xiàn)簡(jiǎn)單的聊天室功能

    C語言實(shí)現(xiàn)簡(jiǎn)單的聊天室功能

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡(jiǎn)單的聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • c++中關(guān)系運(yùn)算符重載的實(shí)現(xiàn)示例

    c++中關(guān)系運(yùn)算符重載的實(shí)現(xiàn)示例

    C++中關(guān)系運(yùn)算符重載允許自定義類型使用關(guān)系運(yùn)算符,重載規(guī)則包括可重載的運(yùn)算符、重載方式、返回值類型、對(duì)稱性、const修飾等,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • C++高性能服務(wù)器框架之線程模塊

    C++高性能服務(wù)器框架之線程模塊

    該模塊基于pthread實(shí)現(xiàn),sylar說,由于c++11中的thread也是由pthread封裝實(shí)現(xiàn)的,并且沒有提供讀寫互斥量,讀寫鎖,自旋鎖等,所以自己封裝了pthread,本文主要詳細(xì)介紹了C++高性能服務(wù)器框架中的線程模塊,需要的朋友可以參考下
    2023-06-06
  • C++中set/multiset容器詳解(附測(cè)試用例與結(jié)果圖)

    C++中set/multiset容器詳解(附測(cè)試用例與結(jié)果圖)

    set/multiset屬于關(guān)聯(lián)式容器,底層結(jié)構(gòu)是用二叉樹實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于C++中set/multiset容器的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • wchar_t,char,string,wstring之間的相互轉(zhuǎn)換

    wchar_t,char,string,wstring之間的相互轉(zhuǎn)換

    以下是對(duì)wchar_t,char,string,wstring之間的相互轉(zhuǎn)換進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2013-09-09

最新評(píng)論

阳山县| 新龙县| 巴塘县| 湖州市| 镇安县| 高安市| 乐昌市| 宜城市| 乌恰县| 泽库县| 黎平县| 禹州市| 县级市| 博客| 三江| 图片| 蓬溪县| 油尖旺区| 郓城县| 柳江县| 南雄市| 武夷山市| 三亚市| 嵊泗县| 祁门县| 莱芜市| 东至县| 静安区| 平凉市| 垫江县| 津南区| 巴东县| 青阳县| 永平县| 谷城县| 平谷区| 夏津县| 宜宾市| 康保县| 青阳县| 丰顺县|