单继承和多继承:
单继承:一个子类只有一个直接父类。
多继承:一个子类有两个或以上的直接父类。
继承方式:继承多个类时,类之间用逗号分隔。
子类类名:继承方式(pubilc/protect/private):父类1,继承方式:父类二,......
菱形继承:在多继承的环境下,两个类的父类相同,并且这两个类被同一个类所继承,此时,便构成了菱形继承。
class A
{
public:
int a;
};
class B:virtual public A
{
public:
int b;
};
class C:virtual public A
{
public:
int b;
int c;
};
class D :public B, public C
{
public:
int d;
};
int main()
{
class D ret;
ret.B::a = 2;
ret.C::a = 3;
ret.b = 4;
ret.c = 5;
ret.d = 6;
如上所示,在编译时会发生错误。
如上所示,由于子类D的两个基类中存在同名变量d,所以在访问的时候,编译器并不能确定要访问的到底是哪个变量。就带来了二义性问题。
解决方法:
在变量名之前加上类名,明确要访问的变量。
菱形继承还会带来数据冗余的问题:
class A
{
public:
int a;
};
class B:virtual public A
{
public:
int b;
};
class C:virtual public A
{
public:
int c;
};
class D :public B, public C
{
public:
int d;
};
int main()
{
class D ret;
ret.B::a = 2;
ret.C::a = 3;
ret.b = 4;
ret.c = 5;
ret.d = 6;
}
由于B和C都继承自A,所以B和C分别会将A的数据和代码进行一份拷贝。而D又继承了B和C,因此在D中,会存储两份A的数据,造成空间的浪费。
而虚继承便很好的解决的菱形继承所带来的问题。
虚继承的实现原理:
下面的图就是上面那个简图的扩展: