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

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

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

什么是多態(tài)?

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

核心概念

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

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

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

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

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

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

虛函數(shù)

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

class A
{

public:
 virtual void() {}
};

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

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

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

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

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

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

最佳實(shí)踐指南

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

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

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

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

虛函數(shù)重寫(xiě)

協(xié)變

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

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

協(xié)變的條件

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

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

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

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ù),沒(méi)有調(diào)?B的析構(gòu)函數(shù),就會(huì)導(dǎo)致內(nèi)存泄漏問(wèn)題,因?yàn)?~B()中在釋放資源。

只有派?類(lèi)Student的析構(gòu)函數(shù)重寫(xiě)了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ù)是重寫(xiě)基類(lèi)的虛函數(shù),編譯器會(huì)檢查以下條件:
    基類(lèi)中是否存在同名虛函數(shù)。
    基類(lèi)和派生類(lèi)的函數(shù)簽名(參數(shù)、常量性、引用限定符)是否嚴(yán)格一致。
    返回類(lèi)型是否符合協(xié)變規(guī)則(如果適用)。
  2. final 關(guān)鍵字
    作用
    final 有兩種用法:
    修飾虛函數(shù):禁止派生類(lèi)重寫(xiě)該虛函數(shù)。
    修飾類(lèi):禁止該類(lèi)被繼承。

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

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

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

多態(tài)的原理

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

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

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

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

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

  1. 基類(lèi)對(duì)象的虛函數(shù)表中存放基類(lèi)所有虛函數(shù)的地址。同類(lèi)型的對(duì)象共?同?張?zhí)摫恚煌?lèi)型的對(duì)象各?有獨(dú)?的虛表,所以基類(lèi)和派?類(lèi)有各?獨(dú)?的虛表。
  2. 派?類(lèi)由兩部分構(gòu)成,繼承下來(lái)的基類(lèi)和??的成員,?般情況下,繼承下來(lái)的基類(lèi)中有虛函數(shù)表指針,??就不會(huì)再?成虛函數(shù)表指針。但是要注意的這?繼承下來(lái)的基類(lèi)部分虛函數(shù)表指針和基類(lèi)對(duì)象的虛函數(shù)表指針不是同?個(gè),就像基類(lèi)對(duì)象的成員和派?對(duì)象中的基類(lèi)對(duì)象成員也獨(dú)?的。
  3. 派?類(lèi)中重寫(xiě)的基類(lèi)的虛函數(shù),派?類(lèi)的虛函數(shù)表中對(duì)應(yīng)的虛函數(shù)就會(huì)被覆蓋成派?類(lèi)重寫(xiě)的虛函數(shù)地址。
  4. 派?類(lèi)的虛函數(shù)表中包含,(1)基類(lèi)的虛函數(shù)地址,(2)派?類(lèi)重寫(xiě)的虛函數(shù)地址完成覆蓋,派?類(lèi)??的虛函數(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;
}
//通過(guò)比較虛表地址,找到其最近的內(nèi)存片段來(lái)確定

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

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

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

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

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

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

• 滿(mǎn)?多態(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++的最小棧,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • c++中l(wèi)og4cplus日志庫(kù)使用的基本步驟和示例代碼

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

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

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

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

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

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

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

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

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

    set/multiset屬于關(guān)聯(lián)式容器,底層結(jié)構(gòu)是用二叉樹(shù)實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于C++中set/multiset容器的相關(guān)資料,文中通過(guò)實(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ì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-09-09

最新評(píng)論

锦屏县| 壶关县| 延川县| 临邑县| 沾化县| 来宾市| 大荔县| 湄潭县| 崇信县| 汝南县| 宁海县| 松阳县| 托克托县| 孟州市| 开化县| 福州市| 兴宁市| 德阳市| 常熟市| 望谟县| 闵行区| 北川| 伊宁县| 济南市| 拜泉县| 镇康县| 襄城县| 阜康市| 新绛县| 林芝县| 招远市| 甘谷县| 肇东市| 扶风县| 寿阳县| 休宁县| 隆林| 盖州市| 安乡县| 弥勒县| 南和县|