成员函数的重载,覆盖与隐藏
1. 重载与覆盖
成员函数被重载特征:
1) 相同的范围内(在同一个类)
2) 函数的名字相同
3) 参数不同
4) Virtual关键字可有可无
覆盖是指派生类函数覆盖基类函数
1) 不同的范围(分别位于派生类和基类中)
2) 函数的名字相同
3) 函数的参数相同
4) 必须有关键字virtual
#include<iostream>
using namespace std;
class Base
{
public:
void f(int x)
{
cout<<"Base::f(int)"<<x<<endl;
}
void f(float x)//重载
{
cout<<"Base::f(float)"<<x<<endl;
}
virtual void g(void)
{
cout<<"Base::g(void)"<<endl;
}
};
class Derived:public Base
{
public:
virtual void g(void)//覆盖
{
cout<<"Derived::g(void)"<<endl;
}
};
void main()
{
Derived d;
Base *pb = &d;
pb->f(42);
pb->f(3.14f);
pb->g();
}
运行结果:
1. 令人迷惑的隐藏规则
隐藏:派生类的函数屏蔽了与其同名的基类函数
1) 如果派生类的函数与基类的函数同名,但参数不同,无论有无关键字,基类的函数都会被隐藏。(注意与重载区分)
2) 如果派生类的函数与基类的函数同名,参数也相同,但是基类函数中没有virtual 关键字,此时基类的函数被隐藏(注意与覆盖区别)
#include<iostream>
using namespace std;
class Base
{
public:
virtual void f(float x)//覆2盖?
{
cout<<"Base::f(int)"<<x<<endl;
}
void g(float x)//隐°t藏?
{
cout<<"Base::g(float)"<<x<<endl;
}
void h(float x)
{
cout<<"Base::h(float)"<<endl;
}
};
class Derived:public Base
{
public:
virtual void f(float x)//覆盖
{
cout<<"Derived::f(float)"<<endl;
}
void g(int x)//隐藏
{
cout<<"Dervied::g(int)"<<endl;
}
void h(float x)//隐藏
{
cout<<"Derived::h(float)"<<endl;
}
};
void main()
{
Derived d;
Base *pb = &d;
Derived *pd = &d;
pb->f(3.14f);
pd->f(3.14f);
pb->g(3.14f);
pd->g(3.14f);
pb->h(3.14f);
pd->h(3.14f);
}
运行结果:
隐藏规则存在的理由:
如果调用函数错误,编译器就会明确指出错误,
如果是派生类有多个基类,(多重继承),有时搞不清楚到底哪些基类定义了要调用的函数,如果没有隐藏规则,可能会调出一个出乎意料的函数。