1. 程式人生 > >C++筆記 第四十八課 同名覆蓋引發的問題---狄泰學院

C++筆記 第四十八課 同名覆蓋引發的問題---狄泰學院

如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習C++編譯環境:Linux

第四十八課 同名覆蓋引發的問題

1.父子間的賦值相容

子類物件可以當做父類物件使用(相容性)
子類物件可以直接賦值給父類物件
子類物件可以直接初始化父類物件
父類指標可以直接指向子類物件
父類引用可以直接引用子類物件

48-1 子類物件的相容性

#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
    int mi;
    int add(int i) 
    {
	mi += i;
    }
    int add(int a, int b)
    {
	mi += (a + b);
    }
};
class Child : public Parent
{
public:
    int mv;
 
    int 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);      //No cover of the same name occurred 沒有發生同名覆蓋?
    rp.add(10, 10);  //No cover of the same name occurred
   
    /* Why is it compiled? 為什麼編譯不過去?*/
    //pp->mv = 1000;
    //pp->add(1, 10, 100);
    return 0;
}

當使用父類指標(引用)指向子類物件時
子類物件退化為父類物件
只能訪問父類中定義的成員
可以直接訪問被子類覆蓋的同名成員

2.特殊的同名函式

子類中可以重定義父類中已經存在的成員函式
這種重定義發生在繼承中,叫做函式重寫
函式重寫是同名覆蓋的一種特殊情況
在這裡插入圖片描述

3.思考

當函式重寫遇上賦值相容會發生什麼?

48-2 賦值相容的問題(**)—好好考慮

#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);    // Expected to print: I'm Parent.
    how_to_print(&c);    // Expected to print: I'm Child.
    
    return 0;
}
執行結果
I'm Parent.
I'm Parent.

4.父子間的賦值相容

問題分析
編譯期間,編譯器只能根據指標的型別判斷所指向的物件
根據賦值相容,編譯器認為父類指標指向的是父類物件
因此,編譯結果只可能是呼叫父類中定義的同名函式
在這裡插入圖片描述
在編譯這個函式的時候,編譯器不可能知道指標p究竟指向了什麼。但是編譯器沒有理由報錯。可是,編譯器認為最安全的做法是呼叫父類的print函式,因為父類和子類肯定都有相同的print函式。

5.問題—自己查詢答案

編譯器的處理方法是合理的嗎?是期望的嗎?合理,不是。
小結
子類物件可以當做父類物件使用(賦值相容
父類指標可以正確的指向子類物件
父類引用可以正確的代表子類物件
子類中可以重寫父類中的成員函式