c++ 繼承之函式隱藏
基類定義了一個虛擬函式 ,派生類如果重寫該方法 (函式名稱和函式引數列表與積累一致 )則在使用派生類物件給基類指標或者引用賦值的時候,採用基類指標或者引用呼叫該函式時,會出現動態呼叫派生類 這是c++的多型特性!
#include<iostream>
using namespace std;
class A
{
public:
virtual void Fun()
{
cout<<"A::Fun()"<<endl;
}
};
class B :public A
{
public:
void Fun(double b)
{
cout<<"B::Fun()"<<endl;
}
//virtual void Fun(double b) 不管有沒有定義成虛擬函式
//會隱藏基類的void
Fun()函式 在主函式中使用B的指標呼叫
//不含引數的Fun函式會產生變異錯誤。
};
class C : public B
{
public:
void Fun(int c)
{
cout<<"C::Fun()"<<endl;
}
//同理 即使B中將virtual void Fun(double b) 定義成虛擬函式
//C定義的 void Fun(int c)會隱藏類B的void Fun(double b)函式 在主函式中使用B的指標呼叫//將C物件賦值給B的指標或者引用 再用該指標或者引用 呼叫Fun函式會產生只會呼叫類///B中的Fun函式。而C從B中繼承的虛擬函式就被隱藏了。
int main()
{
C c;
A& a=c;
B& b=c;
a.Fun();
b.Fun(1);
return 0;
}
輸出結果為:
A::Fun()
B::Fun()
總結:c++中派生類重新定義不會生成函式的兩個過載版本。而是隱藏了基類中的版本。簡而言之:重新定義繼承的方法不是過載。如果在派生類中重新定義函式,將不是使用相同的函式特性標覆蓋基類的申明,而是隱藏同名的基類方法。
這就有兩點必須注意了:
1、如果派生類重定義基類繼承的方法,應確保與原來的原型完全相同。但如果返回型別的是基類引用或者指標,則可以修改為指向派生類的引用或者指標。這種特性被稱為返回型協變。
class A
{
public:
virtual A& Show(){
cout<<"A::Show()"<<endl;
return *this;
}
};
class B:public A
{
public:
virtual B& Show()
{
cout<<"B::Show()"<<endl;
return *this;
}
};
在主函式中 定義 B b;
A& a=b;
a.Fun();
輸出的是 B::Show()
2、如果基類中的虛擬函式被其他虛擬函式過載了,則應在在派生類中重新定義所有的基類版本。
不然會隱藏沒有定義的基類版本。