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、如果基類中的虛函數被其他虛函數重載了,則應在在派生類中重新定義所有的基類版本。

不然會隱藏沒有定義的基類版本。
















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章