成员函数被重载的特征: //////////////////基类中
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是: /////////////基类与子类的关系
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual关键字。
“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: ////////子类中
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
#include
class B {
public:
void mf(){cout<<"1 ";};
};
class D: public B {
public:
void mf(){cout<<"2 ";};
};
main(){
D x;
B *pB = &x;
pB->mf();
D *pD = &x;
pD->mf();
//B bb;
// bb.mf();
}
两种情况下调用的都是对象x的成员函数mf,因为两种情况下都是相同的函数和相同的对象,所以行为会相同,对吗?
对,会相同。但,也许不会相同。特别是,如果mf是非虚函数而D又定义了自己的mf版本,行为就不会相同.
1)当类B中有虚函数mf()时,类D中没有重写此函数时,结果为:1 1。 一般的继承
2)当类B中有虚函数mf()时,类D中重写此函数时,结果为:2 2。 派生类函数覆盖基类函数
3)当类B中有非虚函数mf()时,类D中没有重写此函数时,结果为:1 1。 一般的继承
4)当类B中有非虚函数mf()时,类D中重写此函数时,结果为:1 2。 类D中的函数隐藏了从基类B中继承下来的函数
5)当类B中有虚或非虚函数mf()时,类D中有与此函数同名但时参数不同的函数时,从基类继承而来的函数也被隐藏!
------------------------------------------------------------------------------------------
多重继承的成员调用:
cbase
CBase1:public CBase
CBase2:public CBase
CDervied:public CBase1,CBase2
1)当cbase1与cbase2不是虚继承的时:dervied不能访问基类继承而来(即共有的)的任何成员,不能识别。
2)当cbase1与cbase2是虚继承的时,dervied可以访问cbase中没有1和2重新定义的成员,也能访问只被1或只被2重新定义的成员,这是调用1或2中的成员,当dervied中有重写时,调用derived中重新定义的成员。(共有)
:保证我们在不考虑继承而来的隐藏成员时,能够识别该调用那个类中的!则编译器也能识别!
3)
在调用变量的时候,要指出时属于那个类。