重载、覆盖与隐藏:
★对类层次中的同名成员函数来说,有3种关系:重载(overload)、覆盖(override)和隐藏(hide、oversee),理清3种关系,有助于写出高质量代码。
重载:
重载的概念相对简单,只有在同一类定义中的同名成员函数才存在重载关系,主要特点是函数的参数类型和数目有所不同,但不能出现函数参数的个数和类型均相同,仅仅依靠返回值类型不同来区分的函数,这和普通函数的重载是完全一致的。另外,重载和成员函数是否是虚函数无关,举例来说:
class A
{
……
virtual int fun();
void fun(int);
void fun(double,double);
……
};
上述A类定义中的3个fun函数便是重载关系。
|
覆盖:
★覆盖是指:在派生类中覆盖基类中的同名函数,要求两个函数的参数个数、参数类型、返回类型都相同,且基类函数必须是虚函数。
#include<iostream>
using namespace std;
class A
{
public:
virtual void fun1()
{
cout<<"A::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"A::fun2()"<<endl;
}
};
class B:public A
{
public:
void fun1() // B中的fun1覆盖了A中的fun1,同时继承了A中的fun2
{
cout<<"B::fun1()"<<endl;
}
};
class C:public B
{
public:
void fun2()
{
cout<<"C::fun2()"<<endl; //C类继承了B中的fun1,同时重定义覆盖了fun2
}
};
|
int main()
{
A* p = new C;
p->fun1();
p->fun2();
return 0;
}
|
隐藏:
★隐藏指的是在某些情况下,派生类中的函数屏蔽了基类中的同名函数,这些情况包括:
——2个函数参数相同,但基类函数不是虚函数。和覆盖的区别在于基类函数是否是虚函数。
——2个函数参数不同,无论基类函数是否是虚函数,基类函数都会被屏蔽。和重载的区别在于两个函数不在同一类中。
#include <iostream>
using namespace std;
class A
{
public:
void fun(int xp) //非虚函数,形参int
{ cout<<xp<<endl; }
};
class B : public A
{
public:
void fun(const char * s) //隐藏,oversee,参数为字符串
//参数相同,但是基类不是虚函数,构成隐藏oversee
{ cout<<s<<endl; }
void fun(int xp) //重载
{ cout<<"B::fun()"<<endl; }
};
|
int main()
{
B b;
b.fun("hello");
b.fun(2); //B 中没有void fun(int) 会报错,基类中的被覆盖
return 0;
}
|