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

C++編程之多態(tài)的使用

 更新時間:2025年06月07日 10:27:11   作者:倔強老呂  
這篇文章主要介紹了C++編程之多態(tài)的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

多態(tài)是面向?qū)ο缶幊痰娜筇匦灾唬ǚ庋b、繼承、多態(tài)),它允許使用統(tǒng)一的接口來處理不同類型的對象。在C++中,多態(tài)主要通過虛函數(shù)和繼承機制來實現(xiàn)。

1. 多態(tài)的基本概念

多態(tài)分為兩種:

  • 編譯時多態(tài)(靜態(tài)多態(tài)):通過函數(shù)重載和運算符重載實現(xiàn)
  • 運行時多態(tài)(動態(tài)多態(tài)):通過虛函數(shù)和繼承實現(xiàn)

2. 靜態(tài)多態(tài)

2.1 函數(shù)重載

class Print {
public:
    void show(int i) {
        cout << "整數(shù): " << i << endl;
    }
    void show(double f) {
        cout << "浮點數(shù): " << f << endl;
    }
    void show(string s) {
        cout << "字符串: " << s << endl;
    }
};

int main() {
    Print obj;
    obj.show(5);       // 調(diào)用show(int)
    obj.show(3.14);    // 調(diào)用show(double)
    obj.show("Hello"); // 調(diào)用show(string)
    return 0;
}

2.2 運算符重載

class Complex {
private:
    double real, imag;
public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}
    
    Complex operator + (const Complex& obj) {
        return Complex(real + obj.real, imag + obj.imag);
    }
    
    void display() {
        cout << real << " + " << imag << "i" << endl;
    }
};

int main() {
    Complex c1(3, 4), c2(5, 6);
    Complex c3 = c1 + c2; // 運算符重載
    c3.display(); // 輸出: 8 + 10i
    return 0;
}

3. 動態(tài)多態(tài)(運行時多態(tài))

動態(tài)多態(tài)通過虛函數(shù)和繼承實現(xiàn),是C++中最常用的多態(tài)形式。

3.1 虛函數(shù)

class Base {
public:
    virtual void show() { // 虛函數(shù)
        cout << "Base class show()" << endl;
    }
    void print() { // 非虛函數(shù)
        cout << "Base class print()" << endl;
    }
};

class Derived : public Base {
public:
    void show() override { // 重寫虛函數(shù)
        cout << "Derived class show()" << endl;
    }
    void print() { // 隱藏基類的print()
        cout << "Derived class print()" << endl;
    }
};

int main() {
    Base* bptr;
    Derived d;
    bptr = &d;
    
    // 運行時多態(tài),根據(jù)實際對象類型調(diào)用函數(shù)
    bptr->show(); // 輸出: Derived class show()
    
    // 非虛函數(shù),根據(jù)指針類型調(diào)用函數(shù)
    bptr->print(); // 輸出: Base class print()
    
    return 0;
}

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

class Shape { // 抽象類
public:
    virtual float area() = 0; // 純虛函數(shù)
    virtual void draw() = 0;  // 純虛函數(shù)
};

class Circle : public Shape {
private:
    float radius;
public:
    Circle(float r) : radius(r) {}
    float area() override {
        return 3.14 * radius * radius;
    }
    void draw() override {
        cout << "Drawing Circle" << endl;
    }
};

class Square : public Shape {
private:
    float side;
public:
    Square(float s) : side(s) {}
    float area() override {
        return side * side;
    }
    void draw() override {
        cout << "Drawing Square" << endl;
    }
};

int main() {
    Shape* shapes[2];
    shapes[0] = new Circle(5);
    shapes[1] = new Square(4);
    
    for (int i = 0; i < 2; i++) {
        shapes[i]->draw();
        cout << "Area: " << shapes[i]->area() << endl;
    }
    
    delete shapes[0];
    delete shapes[1];
    return 0;
}

4. 虛析構(gòu)函數(shù)

當基類指針指向派生類對象時,如果基類析構(gòu)函數(shù)不是虛函數(shù),刪除該指針只會調(diào)用基類的析構(gòu)函數(shù),可能導致內(nèi)存泄漏。

class Base {
public:
    Base() { cout << "Base constructor" << endl; }
    virtual ~Base() { cout << "Base destructor" << endl; } // 虛析構(gòu)函數(shù)
};

class Derived : public Base {
public:
    Derived() { cout << "Derived constructor" << endl; }
    ~Derived() { cout << "Derived destructor" << endl; }
};

int main() {
    Base* b = new Derived();
    delete b; // 會調(diào)用Derived的析構(gòu)函數(shù),然后是Base的析構(gòu)函數(shù)
    return 0;
}

5. override和final關鍵字(C++11)

  • override:顯式指明函數(shù)重寫基類虛函數(shù)
  • final:禁止派生類重寫虛函數(shù)或禁止類被繼承
class Base {
public:
    virtual void foo() {}
    virtual void bar() final {} // 不能被子類重寫
};

class Derived : public Base {
public:
    void foo() override {} // 正確:重寫基類虛函數(shù)
    // void bar() override {} // 錯誤:bar是final的
};

class FinalClass final {}; // 不能被繼承
// class TryInherit : public FinalClass {}; // 錯誤

6. 多態(tài)的實現(xiàn)原理

多態(tài)是C++面向?qū)ο缶幊痰暮诵奶匦灾?,其底層實現(xiàn)機制非常精妙。

C++通過虛函數(shù)表(virtual table,簡稱vtable)虛指針(vptr)實現(xiàn)運行時多態(tài):

  • 每個包含虛函數(shù)的類都有一個虛函數(shù)表
  • 每個對象有一個指向虛函數(shù)表的指針(vptr)
  • 調(diào)用虛函數(shù)時,通過vptr找到虛函數(shù)表,再找到實際要調(diào)用的函數(shù)

這種機制雖然有一定開銷,但提供了強大的運行時多態(tài)能力,是C++面向?qū)ο缶幊痰幕?,現(xiàn)代CPU的預測執(zhí)行可以部分緩解這種開銷。

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

1.1 基本結(jié)構(gòu)

虛函數(shù)表(vtable):

  • 編譯器為每個包含虛函數(shù)的類創(chuàng)建一個虛函數(shù)表
  • 表中按聲明順序存儲該類所有虛函數(shù)的地址
  • 是一個靜態(tài)數(shù)組,在編譯時確定

虛指針(vptr):

  • 每個對象內(nèi)部包含一個隱藏的指針成員(vptr)
  • vptr指向該對象所屬類的虛函數(shù)表
  • 由編譯器自動添加和維護

1.2 內(nèi)存布局示例

class Base {
public:
    virtual void func1() { cout << "Base::func1" << endl; }
    virtual void func2() { cout << "Base::func2" << endl; }
    void func3() { cout << "Base::func3" << endl; }
    int a;
};

class Derived : public Base {
public:
    void func1() override { cout << "Derived::func1" << endl; }
    virtual void func4() { cout << "Derived::func4" << endl; }
    int b;
};

內(nèi)存布局示意圖:

Base類對象內(nèi)存布局:
+----------------+
| vptr           | --> 指向Base的vtable
+----------------+
| int a          |
+----------------+

Base的vtable:
+----------------+
| &Base::func1   |
+----------------+
| &Base::func2   |
+----------------+

Derived類對象內(nèi)存布局:
+----------------+
| vptr           | --> 指向Derived的vtable
+----------------+
| int a (繼承)   |
+----------------+
| int b          |
+----------------+

Derived的vtable:
+----------------+
| &Derived::func1| // 重寫的func1
+----------------+
| &Base::func2   | // 未重寫的func2
+----------------+
| &Derived::func4| // 新增的func4
+----------------+

2. 多態(tài)調(diào)用的底層過程

當通過基類指針或引用調(diào)用虛函數(shù)時:

Base* ptr = new Derived();
ptr->func1(); // 多態(tài)調(diào)用

實際執(zhí)行步驟:

  • 通過ptr找到對象的vptr(編譯器知道vptr在對象中的偏移量)
  • 通過vptr找到虛函數(shù)表
  • 在虛函數(shù)表中找到func1對應的條目
  • 調(diào)用該地址處的函數(shù)

3. 構(gòu)造和析構(gòu)過程中的vptr

3.1 構(gòu)造函數(shù)中的vptr初始化

  • 在進入構(gòu)造函數(shù)體之前,編譯器插入代碼初始化vptr
  • 在構(gòu)造過程中,vptr會隨著構(gòu)造的進行而改變
Derived::Derived() {
    // 1. 首先初始化Base部分,此時vptr指向Base的vtable
    // 2. 然后初始化Derived成員,vptr改為指向Derived的vtable
    // 3. 最后執(zhí)行構(gòu)造函數(shù)體
}

3.2 析構(gòu)函數(shù)中的vptr處理

  • 在進入析構(gòu)函數(shù)體之后,vptr首先指向當前類的vtable
  • 析構(gòu)完成后,vptr會被設置為指向基類的vtable
Derived::~Derived() {
    // 1. 執(zhí)行析構(gòu)函數(shù)體(此時vptr指向Derived的vtable)
    // 2. 析構(gòu)Derived特有成員
    // 3. vptr改為指向Base的vtable
    // 4. 調(diào)用Base的析構(gòu)函數(shù)
}

4. 多繼承下的虛函數(shù)表

多繼承情況下,虛函數(shù)表會更復雜:

class Base1 {
public:
    virtual void f1() {}
    int a;
};

class Base2 {
public:
    virtual void f2() {}
    int b;
};

class Derived : public Base1, public Base2 {
public:
    void f1() override {}
    void f2() override {}
    virtual void f3() {}
    int c;
};

內(nèi)存布局:

Derived對象:
+----------------+
| Base1::vptr    | --> 指向Derived的Base1 vtable
+----------------+
| Base1::a       |
+----------------+
| Base2::vptr    | --> 指向Derived的Base2 vtable
+----------------+
| Base2::b       |
+----------------+
| Derived::c     |
+----------------+

Derived的Base1 vtable:
+----------------+
| &Derived::f1   |
+----------------+
| &Derived::f3   |
+----------------+

Derived的Base2 vtable:
+----------------+
| &Derived::f2   |
+----------------+

5. 虛繼承的虛函數(shù)表

虛繼承(virtual inheritance)會使得虛函數(shù)表更加復雜,通常會引入額外的虛基類指針。

6. RTTI(運行時類型信息)

dynamic_cast和typeid也依賴于虛函數(shù)表,通常vtable的第一個條目指向類型信息。

7. 總結(jié)

C++多態(tài)的實現(xiàn)依賴于:

  • 每個類有自己的虛函數(shù)表
  • 每個對象有自己的虛指針
  • 調(diào)用虛函數(shù)時通過虛指針間接查找
  • 繼承關系反映在虛函數(shù)表的布局中

性能考慮:

多態(tài)調(diào)用相比普通函數(shù)調(diào)用有以下開銷:

  • 通過vptr間接訪問虛函數(shù)表
  • 通過虛函數(shù)表間接調(diào)用函數(shù)
  • 通常無法內(nèi)聯(lián)

多態(tài)的應用場景:

  • 實現(xiàn)接口與實現(xiàn)的分離
  • 設計模式(如工廠模式、策略模式等)
  • 回調(diào)函數(shù)
  • 容器存儲不同類型的對象但統(tǒng)一處理

多態(tài)是C++面向?qū)ο缶幊讨蟹浅姶蟮奶匦?,合理使用可以提高代碼的靈活性和可擴展性。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • C++中Qt的安裝與配置步驟詳解

    C++中Qt的安裝與配置步驟詳解

    Qt是一種C++編程框架,用于構(gòu)建圖形用戶界面(GUI)應用程序和嵌入式系統(tǒng),無論是初學者還是經(jīng)驗豐富的開發(fā)者,Qt都為構(gòu)建高質(zhì)量、可維護的應用程序提供了豐富的工具和支持,本文主要給大家介紹了C++中Qt的安裝與配置步驟,需要的朋友可以參考下
    2023-12-12
  • Qt框架中Q_PROPERTY宏的使用

    Qt框架中Q_PROPERTY宏的使用

    Q_PROPERTY是Qt框架中的一個重要宏,用于在QObject派生類中聲明屬性,使得這些屬性可以在QML中直接訪問和修改,本文就來介紹一下Q_PROPERTY宏的使用,感興趣的可以了解一下
    2025-11-11
  • C++單例類模板詳解

    C++單例類模板詳解

    這篇文章主要介紹了C++單例類模板,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • C語言指針應用簡單實例

    C語言指針應用簡單實例

    這篇文章主要介紹了C語言指針應用簡單實例的相關資料,需要的朋友可以參考下
    2017-05-05
  • 對C語言中指針的理解與其基礎使用實例

    對C語言中指針的理解與其基礎使用實例

    這篇文章主要介紹了對C語言中指針的理解與其基礎使用實例,文中援引了知乎熱門問題"為什么說指針是 C 語言的精髓?"中的精彩回答,需要的朋友可以參考下
    2016-03-03
  • C/C++ break和continue區(qū)別及使用方法

    C/C++ break和continue區(qū)別及使用方法

    這篇文章主要介紹了C/C++ break和continue區(qū)別及使用方法的相關資料,需要的朋友可以參考下
    2017-07-07
  • 淺談C++ 虛函數(shù)分析

    淺談C++ 虛函數(shù)分析

    這篇文章主要介紹了淺談C++ 虛函數(shù)分析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • C語言實現(xiàn)旅游資訊管理系統(tǒng)

    C語言實現(xiàn)旅游資訊管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)旅游資訊管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • c++類構(gòu)造函數(shù)詳解

    c++類構(gòu)造函數(shù)詳解

    這篇文章主要介紹了c++類構(gòu)造函數(shù)示例,需要的朋友可以參考下
    2014-05-05
  • C語言之素數(shù)(質(zhì)數(shù))的判斷以及輸出

    C語言之素數(shù)(質(zhì)數(shù))的判斷以及輸出

    這篇文章主要介紹了C語言之素數(shù)(質(zhì)數(shù))的判斷以及輸出方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03

最新評論

徐闻县| 丹江口市| 诸暨市| 宜昌市| 辽阳县| 夏河县| 双流县| 双桥区| 尉氏县| 澎湖县| 怀宁县| 蒙阴县| 聂拉木县| 平潭县| 高陵县| 吴桥县| 西盟| 武平县| 白朗县| 大同县| 龙口市| 瑞安市| 青岛市| 安西县| 达拉特旗| 泗水县| 井冈山市| 诸城市| 盘山县| 晋中市| 广元市| 资源县| 昌邑市| 勃利县| 定襄县| 象山县| 北京市| 来凤县| 武川县| 广昌县| 灵丘县|