91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++重載重寫覆蓋的區別是什么

發布時間:2022-08-08 17:31:49 來源:億速云 閱讀:119 作者:iii 欄目:開發技術

本篇內容介紹了“C++重載重寫覆蓋的區別是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

基類實現

我們先實現一個基類

class BaseTest
{
private:
    virtual void display() { cout << "Base display" << endl; }
    void say() { cout << "Base say()" << endl; }
public:
    virtual void func() { cout << "Base func()" << endl; }
    void exec()
    {
        display();
        say();
    }
    void f1(string a) { cout << "Base f1(string)" << endl; }
    void f1(int a) { cout << "Base f1(int)" << endl; }
    void exec2()
    {
        display();
        say();
    }
};

BaseTest類中我們實現了一個虛函數display和 func。

BaseTest類內部重載了f1函數,實現了兩個版本,一個參數為string一個參數為int。

同一個類中的多個同名函數叫做重載。

實現了普通函數say,exec以及exec2函數。exec和exec2函數內部調用了display和say函數。

子類實現

子類DeriveA繼承了基類

class DeriveA : public BaseTest
{
public:
    void display() { cout << "DeriveA display()" << endl; }
    void f1(int a, int b) { cout << "DeriveA f1(int,int)" << endl; }
    void say() { cout << "DeriveA say()" << endl; }
    virtual void func() { cout << "DeriveA func()" << endl; }
    void use_base_f1(int a, int b)
    {
        BaseTest::f1(2);
        BaseTest::f1("test");
        cout << "DeriveA f1(int, int)" << endl;
    }
    void exec2()
    {
        display();
        say();
    }
};

子類DeriveA 子類重新實現了display和func函數,子類重新實現父類的虛函數,叫做重寫。

同樣子類重新實現了f1和say函數,由于父類有f1和say,所以子類重新實現覆蓋了父類的函數,

這種普通函數被子類重寫導致父類的函數被隱藏了,叫做覆蓋。

函數調用

接下來我們通過函數調用,看一下覆蓋,重載和重寫的區別

void derive_base_test1()
{
    DeriveA a;
    BaseTest *b = &a;
    shared_ptr<BaseTest> c = make_shared<BaseTest>();
    //輸出DeriveA func()
    b->func();
    //輸出DeriveA func()
    a.func();
    //輸出Base f1(string)
    b->f1("abc");
    //輸出Base f1(int)
    b->f1(3);
    //輸出DeriveA f1(int,int)
    a.f1(3, 5);
    a.use_base_f1(2, 4);
    cout << "========================" << endl;
    //輸出DeriveA display()
    //輸出Base say()
    b->exec();
    //輸出DeriveA display()
    //輸出Base say()
    a.exec();
    //輸出Base display
    //輸出Base say()
    c->exec();
    cout << "======================== \n"
         << endl;
    //輸出 DeriveA display()
    //輸出 Base say()
    b->exec2();
    //輸出 DeriveA display()
    //輸出 DeriveA say()
    a.exec2();
    //輸出 Base display
    //輸出 Base say()
    c->exec2();
}

代碼里我們生成了一個DeriveA的實例a, 并將該實例返回給基類BaseTest的指針b,所以:

1 &emsp; b->func();會根據多態的效果調用子類DeriveA的func函數

2 &emsp; a.func() 因為a是一個對象,所以調用子類DeriveA的func函數

3 &emsp; b->f1(“abc”) 調用基類BaseTest的f1,因為f1是一個普通函數

4 &emsp; a.f1(3, 5) 調用DeriveA的f1,因為a是一個普通對象。

5 &emsp; 當我們想在子類里調用基類的f1函數,可以通過基類作用域加函數名的方式,比如例子中的

a.use_base_f1就在函數內部通過BaseTest::f1調用了基類函數f1

6 &emsp; b->exec,首先b是一個指針且exec為普通函數只在基類實現了,所以調用基類的exec,

但是exec內部調用了虛函數display,此時觸發多態機制調用DeriveA的display函數,因為b是一個指向子類DeriveA對象的基類BaseTest指針,exec內部調用了普通函數display,因為display不是虛函數,所以調用BaseTest的display函數

7 &emsp; a.exec(); a是一個DeriveA對象,DeriveA自己沒有實現exec函數,所以調用基類BaseTest的exec函數,exec內部調用display虛函數時由于DeriveA重寫了display函數,所以調用DeriveA的display函數,exec內部調用say函數時由于say是普通函數,所以此時調用的是BaseTest的say函數。

8 &emsp; c->exec(); 因為c為BaseTest類型,所以調用的就是BaseTest的exec,內部執行的也是BaseTest的display和say。

9 &emsp;b->exec2(); 因為b是一個子類BaseTest的指針,所以調用BaseTest的exec2函數,exec2內部調用display時觸發多態機制調用DeriveA的display,調用say時因為say是普通函數,所以調用BaseTest的say函數。

10 &emsp; a.exec2(); 因為a是DeriveA類對象,且DeriveA實現了exec2,所以a調用DeriveA的exec2,這樣exec2內部調用的都是DeriveA的say和display

11 &emsp; c->exec2(); c為BaseTest類對象,所以調用BaseTest類的exec2以及display和say函數。

總結

考察一個函數是被子類還是基類調用時應該分以下幾種情況

1 &emsp;該函數是虛函數并且被子類重寫,如果是基類指針指向子類對象,調用該函數則引發多態機制,調用子類的虛函數

2 &emsp; 如果該函數時虛函數并且沒有被重寫,那么無論調用的對象是基類指針還是子類對象,還是基類對象,

還是子類指針都是調用基類的這個虛函數

3 &emsp; 如果該函數不是虛函數,如果該函數被子類覆蓋(子類重新定義了同名函數),那么調用規則就是子類調用子類的該函數,

基類調用該基類的函數。

4 &emsp; 如果該函數不是虛函數,并且子類沒有定義同名函數(沒有覆蓋基類同名函數),那么無論是子類還是基類的指針或者對象,

統一調用的是基類的函數。

5 &emsp; 如果第4點里基類的函數(沒有被子類覆蓋),但是內部調用了基類的虛函數,并且該虛函數被子類重寫,這時內部這個虛函數調用規則

就要看調用對象的實際類型,符合1的調用標準,多態就走子類,不是多態就走基類(此時符合2標準)

6 &emsp;如果第3點里基類的函數(被子類覆蓋),但是內部調用了基類的虛函數,并且該虛函數被子類重寫,這時內部這個虛函數調用規則

就要看調用對象的實際類型,符合1的調用標準,多態就走子類,不是多態就走基類(此時符合2標準)

“C++重載重寫覆蓋的區別是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

津南区| 景东| 县级市| 莲花县| 徐汇区| 安达市| 丽水市| 左云县| 皋兰县| 田林县| 巴彦淖尔市| 罗源县| 盐津县| 曲周县| 北宁市| 崇州市| 夹江县| 洱源县| 秦安县| 泸定县| 海口市| 五华县| 商水县| 荥阳市| 高碑店市| 辉南县| 敦煌市| 庄浪县| 皋兰县| 剑河县| 仙游县| 漾濞| 揭东县| 松溪县| 红原县| 桦川县| 平昌县| 襄垣县| 平湖市| 大荔县| 右玉县|