您的位置:首页 > 其它

基础备忘:多重继承中的二义性问题

2012-09-02 15:38 267 查看
二义性问题

在多重继承中,需要解决的主要问题是标识符不唯一,即二义性问题。例如,当在派生类继承的多个基类中有同名成员时,派生类中就会出现标识不唯一(二义性)的情况,这在程序中是不允许的。如:

#include<iostream>
using  namespace std;
class Base1
{
public:
int x;
int a();
int b();
int b(int);
int c();
};
class Base2
{
int x;
int a();
public:
float b();
int c();
};
class Derived:Base1,Base2
{};
void d(Derived &e)
{
e.x=10;//错误,二义性
e.a();//错误,二义性
e.b();//错误,二义性
e.c();//错误,二义性
}
int main()
{
Derived ob;
system("pause");
}




在上述代码中,类Derived继承自Base1和类Base2,其中类Base1和类Base2都含有成员x、a()、b()、和c()。在主函数main()中创建Derived的对象ob时,编译系统无法识别void d(Derived &e)函数体中调用的成员继承自哪个基类,因此导致了二义性问题。

在多重继承中,派生类由多个基类派生时,基类之间用逗号隔开,且其每个基类前都必须指明继承方式,否则默认为私有继承。

三种[b]解决方法[/b]

1.使用域运算符::。

2.使用同名覆盖原则。

3.使用虚基类。

1.使用域运算符

如果派生类的基类之间没有继承关系,同时又没有共同的基类,则在引用同名成员时,可在成员名前加上类名和域运算符来区别来自不同其类的成员。例如,将前面范例中的函数d(Derived &e)改写如下。值得注意的是,继承方式也要做出调整,上面代码中全是private继承,如果要能访问到成员需要改成public继承。

void d(Derived &e)
{
e.Base1::x=10;
e.Base1::a();
e.Base2::b();
e.Base1::c();
}
2.使用同名覆盖原则

在派生类中重新定义与基类中同名的成员(如果是成员函数,则参数表也要相同,参数不同为重载)以隐蔽掉基类中的同名成员,在引用这些同名的成员时,引用的就是派生类中的成员,这样二义性问题得到解决。例如:

#include<iostream>
using  namespace std;
class Base
{
public:
int x;
void show()
{
cout<<"基类,x= "<<x<<endl;
}
};
class Derived: public Base
{
public:
int x;
void show()
{
cout<<"继承类,x= "<<x<<endl;
}
};
int main()
{
Derived ob;
ob.x=5;
ob.show();
ob.Base::x=12;
ob.Base::show();
system("pause");
}



在上述代码中,基类Base和派生类Derived都含有数据成员x和成员函数show(),在主函数main()中由派生类Derived创建对象ob后,通过该对象用同名覆盖原则可引用派生类的成员,而通过域运算符可访问基类成员。
3.使用虚基类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  class system float c