国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++ 中的繼承和多態(tài)

這篇具有很好參考價(jià)值的文章主要介紹了C++ 中的繼承和多態(tài)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

C++ 中的繼承和多態(tài)

一、繼承

繼承允許我們依據(jù)一個(gè)類來定義另一個(gè)類,這使得創(chuàng)建和維護(hù)一個(gè)應(yīng)用程序變得更容易。這樣做也達(dá)到了重用代碼功能和提高執(zhí)行效率的效果。

派生類的成員可以直接訪問基類的保護(hù)成員(protected),但不能直接訪問基類的私有成員(private)。不過需要注意的是,派生類的成員函數(shù)只能訪問所作用的那個(gè)對(duì)象(即this指針指向的對(duì)象)的基類保護(hù)成員,不能訪問其他基類對(duì)象的基類保護(hù)成員(比如通過函數(shù)參數(shù)傳來的基類對(duì)象)。

繼承分為公有繼承、保護(hù)繼承與私有繼承,除了公有繼承,剩下兩個(gè)很少用到,三者區(qū)別如下:

C++ 中的繼承和多態(tài)


二、函數(shù)重載、隱藏、覆蓋、重寫

1.函數(shù)重載(Function Overload)

C++規(guī)定在同一作用域中,函數(shù)名相同但函數(shù)特征標(biāo)(即參數(shù)個(gè)數(shù)、類型、順序)不同時(shí),構(gòu)成函數(shù)重載。

函數(shù)重載的注意事項(xiàng):

  1. 返回值類型不能作為重載的標(biāo)準(zhǔn)。
  2. 參數(shù)是否為引用不能作為重載的標(biāo)準(zhǔn),盡管某些時(shí)候能通過編譯,但在調(diào)用時(shí)會(huì)產(chǎn)生二義性。
  3. 成員函數(shù)是否被static修飾也不能作為重載的標(biāo)準(zhǔn),因?yàn)?strong>在通過實(shí)例化后的對(duì)象調(diào)用方法時(shí)無法區(qū)分是否要調(diào)用靜態(tài)成員函數(shù)。
  4. 一個(gè)函數(shù)不能既作為重載函數(shù),又作為有默認(rèn)參數(shù)的函數(shù),因?yàn)楫?dāng)調(diào)用函數(shù)時(shí)如果少寫一個(gè)參數(shù),系統(tǒng)無法判定是利用重載函數(shù)還是利用默認(rèn)參數(shù)的函數(shù),即 int func(int a)int func(int a = 0) 是不能在同一作用域中同時(shí)存在的。

這里還要特別注意一下const修飾函數(shù)或函數(shù)參數(shù)時(shí)的情況:

class A {
public:
    /**
     * 不管形參有沒有const修飾實(shí)參都不會(huì)被修改,二者在調(diào)用時(shí)沒有區(qū)別,因此不能構(gòu)成重載
     */
    void func(int a);
    void func(const int a); // NO

    /**
     * 由底層const修飾的指針指向的實(shí)參不能被修改,二者在調(diào)用時(shí)存在區(qū)別,因此可以構(gòu)成重載
     */
    void func_bot_p(int *a);
    void func_bot_p(const int *a); // YES

    /**
     * 不管有沒有頂層const修飾,該指針指向的內(nèi)容都可以被修改,二者在調(diào)用時(shí)沒有區(qū)別,因此不能構(gòu)成重載
     */
    void func_top_p(int *a);
    void func_top_p(int *const a); // NO

    /**
     * 在const修飾引用時(shí)實(shí)參不能被修改,二者在調(diào)用時(shí)存在區(qū)別,因此可以構(gòu)成重載
     */
    void func_ref(int &a);
    void func_ref(const int &a); // YES

    /**
     * 由const修飾的成員函數(shù)只能由const對(duì)象調(diào)用,二者在調(diào)用時(shí)存在區(qū)別,因此可以構(gòu)成重載
     */
    void func_ret(int a);
    void func_ret(int a) const; // YES
};

2.函數(shù)隱藏(Function Hiding)

不同作用域中定義的同名函數(shù)會(huì)構(gòu)成函數(shù)隱藏(不要求函數(shù)返回值和函數(shù)參數(shù)類型相同)。

類成員函數(shù)會(huì)屏蔽全局函數(shù)派生類成員函數(shù)會(huì)屏蔽與其同名的基類成員函數(shù)(但如果該基類成員函數(shù)為虛函數(shù),且函數(shù)返回值和特征標(biāo)相同則構(gòu)成函數(shù)重寫)。

#include <iostream>

using namespace std;

void func() {
    cout << "global::func()" << endl;
}

class A {
public:
    /**
     * 隱藏了外部的func
     */
    void func() {
        cout << "A::func()" << endl;
    }

    void use_func() {
        func();
        ::func(); // 使用全局函數(shù)時(shí)要加作用域
    }
};

class B : public A {
public:
    /**
     * 隱藏了基類的func
     */
    void func() {
        cout << "B::func()" << endl;
    }

    void use_func() {
        func();
        A::func(); // 使用基類函數(shù)時(shí)要加作用域
    }
};

int main() {
    A a;
    B b;

    a.use_func();
    b.use_func();
}
atreus@MacBook-Pro % g++ main.cpp -o main -std=c++11
atreus@MacBook-Pro % ./main
A::func()
global::func()
B::func()
A::func()
atreus@MacBook-Pro % 

3.函數(shù)重寫與函數(shù)覆蓋(Function Override)

派生類中與基類同返回值類型、同名和同特征標(biāo)虛函數(shù)重定義,構(gòu)成虛函數(shù)覆蓋,也叫虛函數(shù)重寫。

需要注意的是,在默認(rèn)情況下,如果重新定義了繼承的方法,應(yīng)確保與原來的原型完全相同,但如果返回類型是基類引用或指針,則可以修改為指向派生類的引用或指針,這種新出現(xiàn)的特性叫做返回類型協(xié)變(covariance of return type)。

#include <iostream>

using namespace std;

class A {
public:
    void func() {
        cout << "A::func()" << endl;
    }

    virtual void func_v() {
        cout << "A::func_v()" << endl;
    }
};

class B : public A {
public:
    /* 函數(shù)隱藏 */
    void func() {
        cout << "B::func()" << endl;
    }

    /* 函數(shù)重載 */
    void func_v() override {
        cout << "B::func_v()" << endl;
    }
};

int main() {
    A *a = new B;

    a->func();
    a->func_v();

    delete a;
}
atreus@MacBook-Pro % g++ main.cpp -o main -std=c++11 
atreus@MacBook-Pro % ./main
A::func()
B::func_v()
atreus@MacBook-Pro % 

三、多態(tài)

多態(tài)是指一個(gè)方法同時(shí)具有多種形態(tài),具體形態(tài)取決于調(diào)用該方法的具體對(duì)象。從實(shí)現(xiàn)的角度可以將多態(tài)分為編譯時(shí)多態(tài)(主要通過函數(shù)模板、函數(shù)重載和運(yùn)算符重載實(shí)現(xiàn))和運(yùn)行時(shí)多態(tài)(主要通過虛函數(shù)和函數(shù)重寫實(shí)現(xiàn))。

對(duì)于運(yùn)行時(shí)多態(tài),其實(shí)現(xiàn)主要有三個(gè)前提:

  • 存在繼承
  • 存在函數(shù)重寫(覆蓋)。
  • 存在基類指針或者引用指向子類對(duì)象。

運(yùn)行時(shí)多態(tài)的實(shí)現(xiàn)要借助于動(dòng)態(tài)綁定,動(dòng)態(tài)綁定借助于虛函數(shù)實(shí)現(xiàn),虛函數(shù)的限制如下:

  • 只有類的成員函數(shù)才能聲明為虛函數(shù)。
  • 基類的析構(gòu)函數(shù)可以是虛函數(shù)且通常聲明為虛函數(shù)。
  • 構(gòu)造函數(shù)不能為虛函數(shù)。
  • 內(nèi)聯(lián)函數(shù)不能是虛函數(shù)。
  • 靜態(tài)成員函數(shù)不能是虛函數(shù)。

虛函數(shù)、虛函數(shù)表及虛函數(shù)實(shí)現(xiàn)多態(tài)的原理

其中,動(dòng)態(tài)綁定是運(yùn)行時(shí)綁定,通過地址實(shí)現(xiàn),它是指基類的指針或引用有可能指向不同的派生類對(duì)象。對(duì)于非虛函數(shù),執(zhí)行時(shí)實(shí)際調(diào)用該函數(shù)的對(duì)象類型即為該指針或引用的靜態(tài)類型。而對(duì)于虛函數(shù),執(zhí)行時(shí)實(shí)際調(diào)用該函數(shù)的對(duì)象類型為該指針或引用所指對(duì)象的實(shí)際類型。


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

當(dāng)類聲明中包含純虛函數(shù)(定義是末尾有 = 0 的虛函數(shù))時(shí),則不能創(chuàng)建該類的對(duì)象,這個(gè)類變?yōu)?strong>抽象類,C++中的抽象類類似于Java中的接口,抽象類必須至少包含一個(gè)純虛函數(shù)。

此外,對(duì)于抽象類還有以下注意事項(xiàng):

  1. 抽象類只能用作其他類的基類,當(dāng)然也可以作為另一個(gè)抽象類的基類
  2. 抽象類不能用來定義對(duì)象,不能實(shí)例化,也不能用作參數(shù)類型、函數(shù)返回類型或顯式轉(zhuǎn)換的類型。
  3. 如果一個(gè)非抽象類從抽象類中派生,則其必須通過覆蓋來實(shí)現(xiàn)所有的繼承而來的抽象成員函數(shù)。
#include <iostream>

/* 抽象類 */
class Car {
public:
    virtual void showName() = 0; // 純虛函數(shù)
};

class Audi : public Car {
public:
    void showName() override { std::cout << "Audi" << std::endl; }
};

class Volvo : public Car {
public:
    void showName() override { std::cout << "Volvo" << std::endl; }
};

int main() {
    Audi audi;
    Volvo volvo;

    audi.showName(); // Audi
    volvo.showName(); // Volvo

    return 0;
}

五、多重繼承的二義性(菱形繼承)

菱形繼承是指當(dāng)類B和類C同時(shí)繼承于基類A,類D同時(shí)繼承于類B和類C,此時(shí)類A中的成員變量和成員函數(shù)繼承到類D中就變成了兩份,在D中調(diào)用A中的成員會(huì)導(dǎo)致二義性,同時(shí)一個(gè)變量分兩份存儲(chǔ)也存在內(nèi)存空間浪費(fèi)的問題。

C++ 中的繼承和多態(tài)

通過虛基類虛繼承機(jī)制,可以在多繼承中只保留一份共同成員,從而解決了多繼承導(dǎo)致的命名沖突數(shù)據(jù)冗余。

在繼承方式前面加上 virtual 關(guān)鍵字就是虛繼承,如果不采用虛繼承,在類D中使用類A中的m_a時(shí)則需要通過 B::m_aC::m_a 來指定具體使用哪個(gè)m_a。

#include <iostream>

using namespace std;

class A {
protected:
    int m_a = 0;
};

class B : virtual public A {
protected:
    int m_b = 1;
};

class C : virtual public A {
protected:
    int m_c = 2;
};

class D : public B, public C {
protected:
    int m_d = 3;

public:
    D() {
        cout << m_a << endl;
        cout << m_b << endl;
        cout << m_c << endl;
        cout << m_d << endl;
    }
};

int main() {
    D d;
    return 0;
}
atreus@MacBook-Pro % g++ main.cpp -o main -std=c++11
atreus@MacBook-Pro % ./main
0
1
2
3
atreus@MacBook-Pro % 

C++標(biāo)準(zhǔn)庫中的iostream類就是一個(gè)虛繼承的實(shí)際應(yīng)用案例。iostream從istream和ostream直接繼承而來,而istream和ostream又都繼承自一個(gè)共同的名為base_ios的類,是典型的菱形繼承。

C++ 中的繼承和多態(tài)


參考:

https://cloud.tencent.com/developer/article/1177174
https://blog.csdn.net/weixin_39640298/article/details/88725073
http://c.biancheng.net/view/2280.html

C++ 中的繼承和多態(tài)文章來源地址http://www.zghlxwxcb.cn/news/detail-456899.html

到了這里,關(guān)于C++ 中的繼承和多態(tài)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【C++】繼承和多態(tài)

    【C++】繼承和多態(tài)

    繼承機(jī)制是面向?qū)ο蟪绦蛟O(shè)計(jì)使代碼可以 復(fù)用 的最重要的手段,它允許程序員在保持原有類特性的基礎(chǔ)上進(jìn)行 擴(kuò)展 ,增加功能,這樣產(chǎn)生新的類,稱 派生類/子類 。繼承呈現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計(jì)的層次結(jié)構(gòu),體現(xiàn)了由簡(jiǎn)單到復(fù)雜的認(rèn)知過程。以前我們接觸的復(fù)用都是函數(shù)復(fù)

    2024年02月06日
    瀏覽(24)
  • C++基礎(chǔ)篇:07 繼承與多態(tài)

    ????????當(dāng)遇到問題,先看一下現(xiàn)有的類是否能夠解決一部分問題,如果有則繼承,并在此基礎(chǔ)上進(jìn)行擴(kuò)展來解決所有問題,以此縮短解決問題的時(shí)間(代碼復(fù)用) ????????當(dāng)遇到一個(gè)大而復(fù)雜的問題時(shí),可以把復(fù)雜問題拆分成若干個(gè)小問題,為每個(gè)小問題的解決設(shè)計(jì)一

    2024年02月08日
    瀏覽(20)
  • c++面向?qū)ο笾庋b、繼承、和多態(tài)

    c++面向?qū)ο笾庋b、繼承、和多態(tài)

    把客觀事物封裝成類,而且可以把自己的數(shù)據(jù)和方法設(shè)置為只能讓可信的類或者對(duì)象操作,對(duì)不可信的信息進(jìn)行隱藏(利用public,private,protected,friend)實(shí)現(xiàn) has-a :描述一個(gè)類由多個(gè)部件類構(gòu)成,一個(gè)類的成員屬性是另一個(gè)已經(jīng)定義好的類。 use-a:一個(gè)類使用另一個(gè)類,通過類之間

    2024年02月02日
    瀏覽(17)
  • 【C++】繼承和多態(tài)、共有私有和保護(hù)、重寫

    【C++】繼承和多態(tài)、共有私有和保護(hù)、重寫

    繼承是一種機(jī)制,通過它 一個(gè)類可以從另一個(gè)類繼承屬性和方法 。派生類(子類)繼承基類(父類)的成員函數(shù)和數(shù)據(jù)成員,并且可以在其基礎(chǔ)上擴(kuò)展自己的成員函數(shù)和數(shù)據(jù)成員。C++支持多重繼承,即一個(gè)派生類可以同時(shí)從多個(gè)基類中繼承。 多態(tài)是指 同一種操作作用于不同

    2024年02月03日
    瀏覽(25)
  • C++ 面向?qū)ο蠛诵?繼承、權(quán)限、多態(tài)、抽象類)

    繼承(Inheritance)是面向?qū)ο缶幊讨械囊粋€(gè)重要概念,它允許一個(gè)類(稱為派生類或子類)從另一個(gè)類(稱為基類或父類)繼承屬性和方法。繼承是實(shí)現(xiàn)類之間的關(guān)系,通過繼承,子類可以重用父類的代碼,并且可以在此基礎(chǔ)上添加新的功能或修改已有的功能。 在C++中,繼承

    2024年02月08日
    瀏覽(27)
  • C++ 第三彈繼承和多態(tài)-類和對(duì)象

    C++ 第三彈繼承和多態(tài)-類和對(duì)象

    目錄 1.繼承 1.1什么是繼承? 1.2語法格式 1.3繼承權(quán)限 1.4繼承概念語法格式 1.5賦值兼容規(guī)則 1.6繼承體系中的作用域 1.7在繼承體系中的構(gòu)造和析構(gòu) 1.8靜態(tài)成員繼承 1.9友元的繼承 1.10不同繼承方式下子類的對(duì)象模型 1.11繼承和組合 2.多態(tài) 2.1什么是多態(tài) 2.2多態(tài)的分類 2.3實(shí)現(xiàn)條件

    2024年02月10日
    瀏覽(22)
  • c++入門學(xué)習(xí)⑦——繼承和多態(tài)(超級(jí)詳細(xì)版)

    c++入門學(xué)習(xí)⑦——繼承和多態(tài)(超級(jí)詳細(xì)版)

    目錄 前言 繼承 繼承是什么? 為什么會(huì)存在繼承? 語法: 一些基本的定義: 三種繼承方式: 對(duì)象模型 對(duì)于構(gòu)造和析構(gòu)的順序 同名函數(shù)的處理方式 總結(jié): 靜態(tài)成員: 定義: 性質(zhì): 共享數(shù)據(jù)? 編譯階段分配內(nèi)存 類內(nèi)聲明類外初始化 靜態(tài)成員函數(shù) 靜態(tài)成員函數(shù)與普通成員

    2024年02月21日
    瀏覽(26)
  • 【C++】繼承和多態(tài)、public、private、protected、重寫

    【C++】繼承和多態(tài)、public、private、protected、重寫

    繼承是一種機(jī)制,通過它 一個(gè)類可以從另一個(gè)類繼承屬性和方法 。派生類(子類)繼承基類(父類)的成員函數(shù)和數(shù)據(jù)成員,并且可以在其基礎(chǔ)上擴(kuò)展自己的成員函數(shù)和數(shù)據(jù)成員。C++支持多重繼承,即一個(gè)派生類可以同時(shí)從多個(gè)基類中繼承。 多態(tài)是指 同一種操作作用于不同

    2024年02月03日
    瀏覽(22)
  • C++從入門到精通 第九章(繼承和多態(tài))【下】

    (1)一個(gè)面向?qū)ο蟮南到y(tǒng)常常要求一組具有相同基本語義的方法能在同一接口下為不同的對(duì)象服務(wù),這就是多態(tài)性。 (2)在C++中,多態(tài)性可分為編譯時(shí)的多態(tài)性(靜態(tài)多態(tài))和運(yùn)行時(shí)的多態(tài)性(動(dòng)態(tài)多態(tài)),編譯時(shí)的多態(tài)性是通過函數(shù)重載和模板體現(xiàn)的,運(yùn)行時(shí)的多態(tài)性是

    2024年02月21日
    瀏覽(26)
  • python中的類class: 繼承、覆蓋、重寫、重載、擴(kuò)展、多態(tài)、封裝

    python中的類class: 繼承、覆蓋、重寫、重載、擴(kuò)展、多態(tài)、封裝

    使用? class ?創(chuàng)建類。類中有方法、屬性。 1.1 __init__() 函數(shù) 類的內(nèi)置? __init__() ?函數(shù)。所有類都有一個(gè)名為 __init__() 的函數(shù),它在啟動(dòng)類時(shí)執(zhí)行。 使用 __init__() 函數(shù)將值賦給對(duì)象屬性,或者在創(chuàng)建對(duì)象時(shí)需要執(zhí)行的其他操作。 每次使用類創(chuàng)建新對(duì)象時(shí),都會(huì) 自動(dòng)調(diào)

    2024年02月08日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包