派生类 继承了多个相同的成员函数或成员数据!
请看下面的代码:
#include <iostream>
using namespace std;
class h
{
public:
h(int k)
{
b=k;
}
void fun()
{
cout<<"h的函数"<<endl;
}
protected://如果这里为私有的属性就没有了意义 因为在派生类中私有数据是不能被访问的也就更谈不上二义性问题了
int b;
};
class k
{
public:
k(int h)
{
b=h;
}
void fun()
{
cout<<"k的函数"<<endl;
}
protected:
int b;
};
class bm:public h,public k
{
public:
m(int c,int v):h(c),k(v)
{}
void display()
{
//下面这两句会引发二义性 因为编译器不i知道到底使操作 从 类h还是 类k 继承来的 函数 fun() 和数据 b
fun();
b++;
}
};
int main()
{
m x(1,2);
x.fun();//同样这里也会引发二义性!
system("pause");
return 0;
}
解决的办法:
1: 使用类名加上"::"类成员域解析符来 说明到底是操作的哪个基类的成员!
看下面的部分代码:
class m:public h,public k
{
public:
m(int c,int v):h(c),k(v)
{}
void display()
{
现在下面的这两句语句就不会引发二义性了 因为此时编译器已经可以区分出来此时调用的是 类k中的函数fun()和类h中的数据b
k::fun();
h::b++;
}
};
int main()
{
m x(1,2);
x.h::fun();//同样这里就不会引发二义性!编译器直到这里调用的是 类h 中的fun()函数!
system("pause");
return 0;
}
1: 成员覆盖
即在 派生类m中声明和定义 同名的函数fun() 和数据b;即下面的部分改正的代码
class m:public h,public k
{
public:
m(int c,int v):h(c),k(v)
{}
void display()
{ 不会发生二义性了 此时调用的是来自 派生类中同名的 成员数据成员函数!
fun();
b++;
}
void fun()//声明和定义了相同的fun()函数!
{
cout<<"b"<<endl; //这样就覆盖了来自基类继承的同名数据和函数
}
private:
int b; 定义了同名数据 b
};
int main()
{
m x(1,2);
x.fun();//同样这里也不会引发二义性了! 因为这是调用的派生类中的函数 继承而来引发二义性问题的成员已经被自身的成员"覆盖掉"了!
system("pause");
return 0;
}
最后在讲述一下 成员覆盖的问题:
其实也并非覆盖 只是在派生类中出现了和基类同名的成员而以,再加上调用时是根据对象的类型静态调用实际的成员,当然在类中也是调用的是类本身的成员,并非被覆盖说的是:派生类确实继承了来自基类的成员,也确确实实的存在这些成员,这么说吧;在操作派生类中同名的成员时可以说派生类的成员将其屏蔽了,也可以说是作用域的问题 ,当然这只是个人的理解观点,不是权威话语 只是有助于理解记忆才这么认为的,读者根据自己自身来灵活的
理解成员覆盖这个问题!
成员覆盖的解决办法就是 刚刚讲的第一种解决的二义性问题:使用类名加上"::"类成员域解析符来 说明到底是操作的哪个基类的成员!
请看下面的代码:
#include <iostream>
using namespace std;
class h
{
public:
h(int k)
{
b=k;
}
void fun()
{
cout<<"h的函数"<<endl;
}
protected://如果这里为私有的属性就没有了意义 因为在派生类中私有数据是不能被访问的也就更谈不上二义性问题了
int b;
};
class k
{
public:
k(int h)
{
b=h;
}
void fun()
{
cout<<"k的函数"<<endl;
}
protected:
int b;
};
class bm:public h,public k
{
public:
m(int c,int v):h(c),k(v)
{}
void display()
{
//下面这两句会引发二义性 因为编译器不i知道到底使操作 从 类h还是 类k 继承来的 函数 fun() 和数据 b
fun();
b++;
}
};
int main()
{
m x(1,2);
x.fun();//同样这里也会引发二义性!
system("pause");
return 0;
}
解决的办法:
1: 使用类名加上"::"类成员域解析符来 说明到底是操作的哪个基类的成员!
看下面的部分代码:
class m:public h,public k
{
public:
m(int c,int v):h(c),k(v)
{}
void display()
{
现在下面的这两句语句就不会引发二义性了 因为此时编译器已经可以区分出来此时调用的是 类k中的函数fun()和类h中的数据b
k::fun();
h::b++;
}
};
int main()
{
m x(1,2);
x.h::fun();//同样这里就不会引发二义性!编译器直到这里调用的是 类h 中的fun()函数!
system("pause");
return 0;
}
1: 成员覆盖
即在 派生类m中声明和定义 同名的函数fun() 和数据b;即下面的部分改正的代码
class m:public h,public k
{
public:
m(int c,int v):h(c),k(v)
{}
void display()
{ 不会发生二义性了 此时调用的是来自 派生类中同名的 成员数据成员函数!
fun();
b++;
}
void fun()//声明和定义了相同的fun()函数!
{
cout<<"b"<<endl; //这样就覆盖了来自基类继承的同名数据和函数
}
private:
int b; 定义了同名数据 b
};
int main()
{
m x(1,2);
x.fun();//同样这里也不会引发二义性了! 因为这是调用的派生类中的函数 继承而来引发二义性问题的成员已经被自身的成员"覆盖掉"了!
system("pause");
return 0;
}
最后在讲述一下 成员覆盖的问题:
其实也并非覆盖 只是在派生类中出现了和基类同名的成员而以,再加上调用时是根据对象的类型静态调用实际的成员,当然在类中也是调用的是类本身的成员,并非被覆盖说的是:派生类确实继承了来自基类的成员,也确确实实的存在这些成员,这么说吧;在操作派生类中同名的成员时可以说派生类的成员将其屏蔽了,也可以说是作用域的问题 ,当然这只是个人的理解观点,不是权威话语 只是有助于理解记忆才这么认为的,读者根据自己自身来灵活的
理解成员覆盖这个问题!
成员覆盖的解决办法就是 刚刚讲的第一种解决的二义性问题:使用类名加上"::"类成员域解析符来 说明到底是操作的哪个基类的成员!