基类定义了一个虚函数 ,派生类如果重写该方法 (函数名称和函数参数列表与积累一致 )则在使用派生类对象给基类指针或者引用赋值的时候,采用基类指针或者引用调用该函数时,会出现动态调用派生类 这是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、如果基类中的虚函数被其他虚函数重载了,则应在在派生类中重新定义所有的基类版本。
不然会隐藏没有定义的基类版本。