C++中关于虚继承子类的访问权限问题
在C++中,多继承会造成子类存在数据冗余即在子类中存在多份顶层父类的数据拷贝,以如下继承关系为例:
class Base
{
public:
int n0;
void func()
{
cout<<"Base::func()"<<endl;
}
};
class b1: public Base
{
public:
int n1;
};
class b2 : public Base
{
public:
int n2;
};
class d:public b1,public b2
{
public:
int n3;
};
类继承关系如图
我们发现在子类d中,存在两份基类Base的数据及函数,所以造成了数据冗余,而且在访问基类的成员时必须使用如下方式
d dd;
dd.b1::func();
//或者
dd.b2::func();
为了解决这个问题引入了虚继承,仍以上述继承关系为例,虚继承如下
class Base
{
public:
int n0;
void func()
{
cout<<"Base::func()"<<endl;
}
};
class b1: virtual public Base
{
public:
int n1;
};
class b2:virtual public Base
{
public:
int n2;
};
class d:public b1,public b2
{
public:
int n4;
void func()
{
cout<<"d::func()"<<endl;
}
};
继承体系如图
此时不存在数据冗余问题,基类中的数据成员在子类中只有一份
但是假如继承时不使用public继承,那么子类d对基类Base的公有成员的访问权限是如何确定的呢,这个是由d继承b1,b2时最高权限的那个类和那个类继承Base的权限,两者取最低权限得到的。
如例1:
class Base
{
public:
int n0;
void func()
{
cout<<"Base::func()"<<endl;
}
};
class b1: virtual public Base
{
public:
int n1;
};
class b2:virtual protected Base
{
public:
int n2;
};
class d:public b1,private b2
{
public:
int n4;
void func()
{
cout<<"d::func()"<<endl;
}
};
d对b1,b2中最高权限是public(b1),b1继承Base的权限是public,因此最终权限就是min(public,public)即public。此时可以理解为子类选择了b1类的那条路径来进行基类数据的访问。
此时需要通过子类访问基类的func()函数就可以通过
d dd;
dd.b1::func(); //基类Base的函数
dd.func()//子类d中函数,发生了覆盖
```
>假设存在如下情况
```
class Base
{
public:
int n0;
void func()
{
cout<<"Base::func()"<<endl;
}
};
class b1: virtual private Base
{
public:
int n1;
void f()
{
func();
}
};
class b2:virtual public Base
{
public:
int n2;
};
class d:public b1,public b2
{
public:
int n4;
void func()
{
}
};
此时d对b1,b2中最高权限是public(b1,b2),那么他会选择哪个呢,答案是b1,b2 中继承Base权限最高的那个,本例中就是选择b2,因为b1继承Base是private,而b2是public。
- 综上所述,在虚继承中子类会尽量选择最高的权限作为最终对基类成员的访问级别。