11.5.3 隐藏
隐藏指的是在某些情况下,派生类中的函数屏蔽了基类中的同名函数,如下所述。
❑派生类中的函数与基类中的函数参数相同,但基类函数不是虚函数,同覆盖的区别在于基类函数是否是虚函数。
❑派生类中的函数与基类中的函数参数不同,不管基类函数是否是虚函数,基类函数都会被屏蔽,同重载的区别在于两个函数不在同一类中。
“屏蔽”指的是使用派生类对象调用其成员函数(静态联编)时,基类中的函数将不会被执行,执行的是派生类中的函数,即使传递的参数符合基类中的函数参数列表,基类函数也不会执行,编译器会给出错误提示,这相当于把基类的成员函数“隐藏”了起来,即命名的由来。如示例代码11.13所示。
代码11.13 类层次结构中的函数隐藏Oversee
<————————————-文件名:example1113.cpp——————————————> 01 #include<iostream> 02 using namespace std; 03 class A//类A的定义 04 { 05 public: 06 void fun(int xp)//非虚成员函数fun,参数为int型 07 { 08 cout<<xp<<endl; 09 } 10 }; 11 class B:public A//类B由类A派生而来 12 { 13 public: 14 void fun(char*s)//覆盖,oversee,参数为字符串 15 { 16 cout<<s<<endl; 17 } 18 }; 19 int main() 20 { 21 B obB;//声明一个类B对象 22 obB. fun("hello");//字符串参数版本 23 obB. fun(2);//错误,发生覆盖,找不到fun(int) 24 return 0; 25 }编译链接,系统给出错误信息如下所示。 cannot convert parameter 1 from'const int'to'char*'
【代码解析】代码11.13说明,基类A中定义的fun函数已经被代码第14行类B中定义的fun函数覆盖,使其不可见,在类B中重载fun函数可有效地解决这一问题,将类B的定义修改为如下所示。
class B:public A { public: void fun(char*s) { cout<<s<<endl; } void fun(int xp)//重载 { A:fun(xp); } };重新编译运行,
输出结果如下所示。
hello 2
读者通过对类B的修改过程可以更进一步地理解覆盖、重载以及隐藏的区别。