如果派生類中的成員(包括成員變量和成員函數)和基類中的成員重名,那麼就會遮蔽從基類繼承過來的成員。所謂遮蔽,就是在派生類中使用該成員(包括在定義派生類時使用,也包括通過派生類對象訪問該成員)時,實際上使用的是派生類新增的成員,而不是從基類繼承來的。
下面是一個成員函數的名字遮蔽的例子:
#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教程《類繼承時的作用域嵌套》一節中講解,屆時讀者必將有所頓悟。