多继承
我们可以从一个类继承,我们也可以能同时从多个类继承,这就是多继承。
格式
class 子类 : 继承方式1 父类名1,继承方式2 父类名2,继承方式3 父类名3....
{
};//表示子类由父类1、2、3....共同派生出来
class Base1
{
public:
int a;
};
class Base2
{
public:
int b;
};
class Son:public Base1,public Base2
{
//Son类 拥有了a b
};
int main(int argc, char *argv[])
{
Son ob;
ob.a = 100;
ob.b = 200;
return 0;
}
多继承容易产生二义性
class Base1
{
public:
int a;
};
class Base2
{
public:
int a;
};
class Son:public Base1,public Base2
{
};
int main(int argc, char *argv[])
{
Son ob;
//ob.a = 100;//err Base1 和 Base2中都有a成员同名
//解决办法:加作用域
ob.Base1::a = 100;
ob.Base2::a = 200;
return 0;
}
菱形继承(具有公共祖先的多继承)
class Animal
{
public:
int data;
};
class Sheep:public Animal
{
public:
};
class Tuo:public Animal
{
public:
};
class SheepTuo:public Sheep,public Tuo
{
public:
};
int main(int argc, char *argv[])
{
SheepTuo st;
//SheepTuo 从Sheep中继承data 从Tuo继承data 就产生二义性
//st.data = 200;//err
//第一种方式:加作用域解决
st.Sheep::data = 200;
st.Tuo::data = 300;
return 0;
}
普通继承 分析
class Animal
{
public:
int data;
};
class Sheep:public Animal
{
public:
};
class Tuo:public Animal
{
public:
};
class SheepTuo:public Sheep,public Tuo
{
public:
};
虚继承
virtual修饰继承方式
class 子类:virtual public 父类
{
};
继承的动作为虚继承,父类称为虚基类
虚继承分析
class Animal
{
public:
int data;
};
class Sheep:virtual public Animal
{
public:
};
vbptr(虚基类指针)
vbtable(虚基类表)保存了当前的虚指针相对于虚基类的首地址的偏移量
class Tuo:virtual public Animal
{
public:
};
产生 vbptr和vbtable的目的是保证不管多少个继承,虚基类的数据只有一份。
class SheepTuo:public Sheep,public Tuo
{
public:
};
注意
虚继承只能解决具备公共祖先的多继承所带来的二义性问题,不能解决没有公共祖先的多继承的。
虚继承:不管继承多少次,虚基类只有一份数据。