中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

同名覆蓋引發的問題(四十一)

發布時間:2020-07-19 15:46:13 來源:網絡 閱讀:2212 作者:上帝之子521 欄目:編程語言

        在子類繼承父類后,子類對象便可以當做父類對象使用了(兼容性)。包括:1、子類對象可以直接賦值給父類對象;2、子類對象可以直接初始化父類對象;3、父類對象可以直接指向子類對象;4、父類引用可以直接引用子類對象。那么我們來編程看看子類對象的兼容性

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    int mi;
    
    void add(int v)
    {
        mi += v;
    }
    
    void add(int a, int b)
    {
        mi += (a + b);
    }
};

class Child : public Parent
{
public:
    int mv;
    
    void add(int a, int b, int c)
    {
        mv += (a + b + c);
    }
};

int main()
{
    Parent p;
    Child c;
    
    p = c;
    
    Parent p1(c);
    
    Parent& rp = c;
    Parent* pp = &c;
    
    rp.mi = 100;
    rp.add(5);
    rp.add(10, 10);
    
    //pp->mv = 1000;
    //pp->add(1, 10, 100);
    
    return 0;
}

        我們先來看看第 38 行將子類對象 c 直接賦值給父類對象 p,這樣編譯會通過嗎?還有第 40 行的初始化操作。再將子類對象 c 賦值給父類對象的引用 rp,將父類對象的指針 pp 指向對象 c 的地址。通過 rp 調用父類對象的成員變量和成員函數,看看會報錯嗎?照理說這塊應該會發生同名覆蓋,我們看看編譯結果

同名覆蓋引發的問題(四十一)

        編譯是通過的,也就證明沒有發生同名覆蓋。那么我們再來將第 49 和 50 行的注釋去掉,看看通過指針 pp 指向的子類對象 c 直接調用子類對象的成員變量和成員函數會通過嗎?

同名覆蓋引發的問題(四十一)

        我們看到編譯出錯了。下來我們來說下當使用父類指針(引用)指向子類對象時,子類對象便退化為父類對象,只能訪問父類中定義的成員,可以直接訪問被子類覆蓋的同名成員。這也就不難解釋上面沒有發生同名覆蓋以及通過指針來調用子類對象的成員變量和成員函數出錯的情況了。

        在子類中可以重定義父類中已經存在的成員函數,這種重定義發生在繼承中,叫做函數重寫函數重寫是同名覆蓋的一種特殊情況。當函數重寫遇上賦值兼容會發生什么呢?我們通過是來代碼來分析下

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    void print()
    {
        cout << "I'm Parent!" << endl;
    }
};

class Child : public Parent
{
public:
    void print()
    {
        cout << "I'm Child!" << endl;
    }
};

void how_to_print(Parent* p)
{
    p->print();
}

int main()
{
    Parent p;
    Child c;
    
    p.print();         // I'm Parent!
    c.print();         // I'm Child!
    
    cout << endl;
    
    how_to_print(&p);  // I'm Parent!
    how_to_print(&c);  // I'm Child!
    
    return 0;
}

        我們分別在父類和子類中定義 print 函數,打印相關信息。我們期望的是 p.print() 打印的是 I'm Parent!;c.print() 打印的是 I'm Child!;在調用全局函數 how_to_print() 時,如果傳入的是父類指針,我們期望打印的是 I'm Parent!,如果傳入的是子類指針,則打印的是 I'm Child!。下來我們來編譯看看結果

同名覆蓋引發的問題(四十一)

        我們直接調用的時候打印的是對的,但是在傳入對象的時候,打印的是錯的。我們傳入的是子類對象,但是打印出來的是父類的函數,我們會不會很奇怪呢?在編譯期間,編譯器只能根據指針的類型判斷所指向的對象,根據賦值兼容,編譯器認為父類指針指向的是父類對象。因此,編譯結果只可能是調用父類中定義的同名函數。那么在編譯到 how_to_print(Parent* p) 這個函數時,編譯器不可能知道指針 p 究竟指向了什么。但是編譯器沒有理由報錯。于是乎,編譯器認為最安全的做法是調用父類的 print 函數,因為父類和子類肯定都有相同的 print 函數。因此便出現了這個編譯結果,那么編譯器的處理方法是合理的嗎?是期望的嗎?顯然從安全的角度來說,它的處理是合理的,但卻不是我們所期望的。在后面我們會繼續講解這個問題的。

        通過對同名覆蓋的學習,總結如下:1、子類對象可以當做父類對象使用(賦值兼容);2、父類指針可以正確的指針子類對象;3、父類引用可以正確的代表子類對象;4、子類中可以重寫父類中的成員函數。


        歡迎大家一起來學習 C++ 語言,可以加我QQ:243343083

向AI問一下細節

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

AI

威宁| 松江区| 廉江市| 张家界市| 龙岩市| 吐鲁番市| 康乐县| 十堰市| 博兴县| 延长县| 仙游县| 开远市| 汽车| 常熟市| 霞浦县| 郴州市| 黄平县| 贵阳市| 泽库县| 乌什县| 焉耆| 许昌市| 黄冈市| 罗山县| 阜阳市| 阿拉善左旗| 即墨市| 任丘市| 淳化县| 洪江市| 开原市| 德令哈市| 武隆县| 鄱阳县| 周至县| 隆安县| 丹东市| 开平市| 宁蒗| 惠安县| 汶川县|