只要成员名称一样(即使base classes和derived classes内的函数有不同的参数类型,而且不论函数是vitual或non-virtual),继承类中的名称就会遮掩base class内的名称。
表现如下:
#include<iostream> using namespace std; class Base { public: void mf1() {cout<<"Base::mf1"<<endl;} void mf1(int a) {cout<<"Base::mf1(int)"<<endl;} void mf2() {cout<<"Base::mf2"<<endl;} }; class Derived:public Base { public: void mf1() {cout<<"Derived::mf1"<<endl;} void mf2() {cout<<"Derived::mf2"<<endl;} void CallBase() {Base::mf1();} }; int main() { Derived d; d.mf1(); d.CallBase();//正确。如果在类体内通过Base::mf1();则可调用父类的同名函数。 d.mf1(1);//报错 no matching function for call to `Derived::mf1(int)' //candidates are: void Derived::mf1() getchar(); }在Base中有mf1(int )函数,但是在Derived类中,已经重载了mf1函数,所以把Base中的所有同名函数都遮掩了。只有mf1()可以通过Derived对象直接调用。
可以Derived类体中直接通过其它函数调用Base中没有被同名遮掩的成员函数,或者通过Derived对象都可以直接调用Base中没有被同名遮掩的成员函数。(前提是满足public\protected\private的继承约束)。例:
#include<iostream> using namespace std; class Base { public: void init() {cout<<"Base::init"<<endl;} void mf1(int a) {cout<<"Base::mf1(int)"<<endl;} void mf2() {cout<<"Base::mf2"<<endl;} }; class Derived:public Base { public: void CallBase() {init();} }; int main() { Derived d; d.CallBase();//正确 d.init();//正确 getchar(); }输出:
一个virtual函数的例子:
#include<iostream> using namespace std; class Base { public: void init() {mf1();} private: virtual void mf1() {cout<<"Base::mf1"<<endl;} }; class Derived:public Base { private: virtual void mf1() {cout<<"Derived::mf1"<<endl;} }; int main() { Derived d; d.init();//正确 Base b; b.init(); Base &tb=d; tb.init(); getchar(); }
通过基类的init()访问不同类型的mf1(),实现多态。
如果private继承则:
#include<iostream> using namespace std; class Base { public: void init() {mf1();} private: virtual void mf1() {cout<<"Base::mf1"<<endl;} }; class Derived:private Base { private: virtual void mf1() {cout<<"Derived::mf1"<<endl;} }; int main() { Derived d; // d.init();//报错:`void Base::init()' is inaccessible //`Base' is not an accessible base of `Derived' Base b;//正确 b.init();//正确 // Base &tb=d;//报错 `Base' is not an accessible base of `Derived' // tb.init(); getchar(); }
上面代码再变化,把d存到Base b中,造成切割后:
#include<iostream> using namespace std; class Base { public: void init() {mf1();} private: virtual void mf1() {cout<<"Base::mf1"<<endl;} }; class Derived:public Base { private: virtual void mf1() {cout<<"Derived::mf1"<<endl;} }; int main() { Derived d; Base b=d;//Derived部分被切割掉了,结果只剩下基类的mf1可供选择了。 b.init(); getchar(); }结果:
通过using声明式让被遮掩的成员函数重见天日:
#include<iostream> using namespace std; class Base { public: void mf1() {cout<<"Base::mf1"<<endl;} void mf1(int x) {cout<<"Base::mf1(int)"<<endl;} }; class Derived:public Base { public: using Base::mf1;//这里用了using 声明式 void mf1() {cout<<"Derived::mf1"<<endl;} }; int main() { Derived d; d.mf1(); d.mf1(1);//有了using Base::mf1 就Derived对象就可以访问基类中被遮掩的同名函数了 getchar(); }
通过using声明式,在Derived类中引入基类被隐藏的函数。
通过转交函数让基类中的函数重见天日:
#include<iostream> using namespace std; class Base { public: void mf1() {cout<<"Base::mf1"<<endl;} void mf1(int x) {cout<<"Base::mf1(int)"<<endl;} }; class Derived:public Base { public: void mf1() {Base::mf1();} //转交 }; int main() { Derived d; d.mf1(); getchar(); }结果:
个人补充:直接加上作用域符来显式调用基类同名函数
如:
#include<iostream> using namespace std; class A { public: void fun(){cout<<"A::fun"<<endl;} }; class B:public A { public: void fun(){cout<<"B::fun"<<endl;} }; void Test() { B d; d.fun(); d.A::fun(); } int main() { Test(); getchar(); return 0; }结果: