1. 程式人生 > >c++ 繼承之函式隱藏

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

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