只要成员名称一样(即使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;
}
结果: