程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++基礎知識 >> C++繼承時的名字遮蔽

C++繼承時的名字遮蔽

編輯:C++基礎知識
如果派生類中的成員(包括成員變量和成員函數)和基類中的成員重名,那麼就會遮蔽從基類繼承過來的成員。所謂遮蔽,就是在派生類中使用該成員(包括在定義派生類時使用,也包括通過派生類對象訪問該成員)時,實際上使用的是派生類新增的成員,而不是從基類繼承來的。

下面是一個成員函數的名字遮蔽的例子:
#include<iostream>
using namespace std;

//基類People
class People{
public:
    void show();
protected:
    char *m_name;
    int m_age;
};
void People::show(){
    cout<<"嗨,大家好,我叫"<<m_name<<",今年"<<m_age<<"歲"<<endl;
}

//派生類Student
class Student: public People{
public:
    Student(char *name, int age, float score);
public:
    void show();  //遮蔽基類的show()
private:
    float m_score;
};
Student::Student(char *name, int age, float score){
    m_name = name;
    m_age = age;
    m_score = score;
}
void Student::show(){
    cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<endl;
}

int main(){
    Student stu("小明", 16, 90.5);
    //使用的是派生類新增的成員函數,而不是從基類繼承的
    stu.show();
    //使用的是從基類繼承來的成員函數
    stu.People::show();

    return 0;
}
運行結果:
小明的年齡是16,成績是90.5
嗨,大家好,我叫小明,今年16歲

本例中,基類 People 和派生類 Student 都定義了成員函數 show(),它們的名字一樣,會造成遮蔽。第 37 行代碼中,stu 是 Student 類的對象,默認使用 Student 類的 show() 函數。

但是,基類 People 中的 show() 函數仍然可以訪問,不過要加上類名和域解析符,如第 39 行代碼所示。

基類成員函數和派生類成員函數不構成重載

基類成員和派生類成員的名字一樣時會造成遮蔽,這句話對於成員變量很好理解,對於成員函數要引起注意,不管函數的參數如何,只要名字一樣就會造成遮蔽。換句話說,基類成員函數和派生類成員函數不會構成重載,如果派生類有同名函數,那麼就會遮蔽基類中的所有同名函數,不管它們的參數是否一樣。

下面的例子很好的說明了這一點:
#include<iostream>
using namespace std;

//基類Base
class Base{
public:
    void func();
    void func(int);
};
void Base::func(){ cout<<"Base::func()"<<endl; }
void Base::func(int a){ cout<<"Base::func(int)"<<endl; }

//派生類Derived
class Derived: public Base{
public:
    void func(char *);
    void func(bool);
};
void Derived::func(char *str){ cout<<"Derived::func(char *)"<<endl; }
void Derived::func(bool is){ cout<<"Derived::func(bool)"<<endl; }

int main(){
    Derived d;
    d.func("c.biancheng.net");
    d.func(true);
    d.func();  //compile error
    d.func(10);  //compile error
    d.Base::func();
    d.Base::func(100);

    return 0;
}
本例中,Base 類的func()func(int)和 Derived 類的func(char *)func(bool)四個成員函數的名字相同,參數列表不同,它們看似構成了重載,能夠通過對象 d 訪問所有的函數,實則不然,Derive 類的 func 遮蔽了 Base 類的 func,導致第 26、27 行代碼沒有匹配的函數,所以調用失敗。

如果說有重載關系,那麼也是 Base 類的兩個 func 構成重載,而 Derive 類的兩個 func 構成另外的重載。

至於 Base 類和 Derived 類的 4 個 func 為什麼不會構成重載,我們將在VIP教程《類繼承時的作用域嵌套》一節中講解,屆時讀者必將有所頓悟。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved