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

溫馨提示×

溫馨提示×

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

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

C++--同名覆蓋、多態

發布時間:2020-07-20 23:31:08 來源:網絡 閱讀:275 作者:淡淡_小孩 欄目:編程語言

一.同名覆蓋引發的問題

父子間的賦值兼容--子類對象可以當作父類對象使用(兼容性)
1.子類對象可以直接賦值給父類對象
2.子類對象可以直接初始化父類對象
3.父類指針可以指向子類對象
4.父類引用可以直接引用子類對象

代碼示例

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    int mi;

    void add(int i)
    {
        mi += i;
    }

    void add(int a, int b)
    {
        mi += (a + b);
    }
};

class Child : public Parent
{
public:
    int mv;

    void add(int x, int y, int z)
    {
        mv += (x + y + z);
    }
};

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;
}

對該代碼進行結果預測:通過之前的學習的同名覆蓋,程序會在 rp.add(5); rp.add(10, 10); 進行同名覆蓋,且在父類指針指向子類對象時可以進行調用
運行結果
C++--同名覆蓋、多態
通過程序的運行結果看到,與預測的結果不同,這是因為當使用父類指針(引用)指向子類對象時
1.子類對象退化為父類對象--所以在pp->mv時會出錯
2.只能訪問父類中定義的成員
3.可以直接訪問被子類覆蓋的同名成員--所以沒發生同名覆蓋

特殊的同名函數

1.子類中可以重定義父類中已經存在的成員函數
2.這種重定義發生在繼承中,叫做函數重寫
3.函數重寫是同名覆蓋的一種特殊情況
C++--同名覆蓋、多態

Q:當函數重寫遇上賦值兼容會發生什么?
代碼示例

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    int mi;

    void add(int i)
    {
        mi += i;
    }

    void add(int a, int b)
    {
        mi += (a + b);
    }

    void print()
    {
        cout << "I'm Parent." << endl;
    }
};

class Child : public Parent
{
public:
    int mv;

    void add(int x, int y, int z)
    {
        mv += (x + y + z);
    }

    void print()
    {
        cout << "I'm Child." << endl;
    }
};

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

int main()
{
    Parent p;
    Child c;

    how_to_print(&p);    
    how_to_print(&c);    

    return 0;
}

輸出結果
C++--同名覆蓋、多態
問題分析
1.編譯期間,編譯器只能根據指針的類型判斷所指向的對象
2.根據賦值兼容,編譯器認為父類指針指向的是父類對象
3.因此,編譯結果只可能是調用父類中定義的同名函數
C++--同名覆蓋、多態
在編譯這個函數的時候,編譯器不可能知道指針p指向了什么,但是編譯器沒有理由報錯。于是,編譯器認為最安全的做法時調用父類的print函數,因為父類和子類肯定都有相同的print函數

二.多態的概念和意義

函數重寫
1.父類中被重寫的函數依然會繼承給子類
2.子類中重寫的函數將覆蓋父類中的函數
3.通過作用域分辨符(::)可以訪問父類中的函數

A.面向對象中期待的行為
1.根據實際的對象類型判斷如何調用重寫函數
2.父類指針指向--a.父類對象調用父類中定義的函數b.子類對象則調用子類中定義的函數
B.面向對象的多態的概念
1.根據實際的對象類型決定函數調用的具體目標
2.同樣的調用語句在實際運行時有多種不同的表現形態
C++--同名覆蓋、多態
C.C++語言中直接支持多態的概念
1.通過使用virtual關鍵字對多態進行支持
2.被virtual聲明的函數被重寫后具有多態特性
3.被virtual聲明的函數叫做虛函數

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    virtual 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;

    how_to_print(&p);    
    how_to_print(&c);    

    return 0;
}

運行結果
C++--同名覆蓋、多態
D.多態的意義
1.在程序的運行過程中展現出多態的特性
2.函數重寫必須實現多態,否則沒有意義
3.多態時面向對象組件化程序設計的基礎特性

靜態聯編--在程序的編譯期間就能確定具體的函數調用
動態聯編--在程序實際運行后才能確定具體的函數調用

#include <iostream>
#include <string>

using namespace std;

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

    virtual void func(int i)
    {
        cout << "void func(int i) : " << i << endl;
    }

    virtual void func(int i, int j)
    {
        cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl;
    }
};

class Child : public Parent
{
public:
    void func(int i, int j)
    {
        cout << "void func(int i, int j) : " << i + j << endl;
    }

    void func(int i, int j, int k)
    {
        cout << "void func(int i, int j, int k) : " << i + j + k << endl;
    }
};

void run(Parent* p)
{
    p->func(1, 2);     // 展現多態的特性
                       // 動態聯編
}

int main()
{
    Parent p;

    p.func();         
    p.func(1);      
    p.func(1, 2);     

    cout << endl;

    Child c;

    c.func(1, 2);     

    cout << endl;

    run(&p);
    run(&c);

    return 0;
}

運行結果
C++--同名覆蓋、多態
小結
1.函數重寫只可能發生在父類與子類之間
2.根據實際對象的類型確定調用的具體函數
3.virtual關鍵字是C++中支持多態的唯一方式
4.被重寫的虛函數表現出多態的特性

向AI問一下細節

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

AI

安义县| 衡阳市| 五常市| 莒南县| 台江县| 油尖旺区| 边坝县| 海晏县| 徐闻县| 商河县| 湖州市| 岳普湖县| 蓝山县| 吉木乃县| 汕尾市| 武安市| 遵义市| 门头沟区| 嘉兴市| 富平县| 乌海市| 韶关市| 越西县| 三原县| 阜平县| 罗源县| 始兴县| 襄城县| 新泰市| 隆回县| 青阳县| 建德市| 定州市| 桃园县| 镇巴县| 丰顺县| 柳林县| 修文县| 阿鲁科尔沁旗| 临邑县| 琼海市|