继承
继承格式
//Student--派生类 public--继承方式 Person--基类
class Student : public Person
{
public:
int _stuid;//学号
int _major;//专业
}
继承权限
访问权限|继承权限 | public | protected | private |
---|---|---|---|
public | public | protected | private |
protected | protected | protected | private |
private | 不能访问 | 不能访问 | 不能访问 |
- pirvate不可见,不能访问,但实际上被继承下来了
- public>protected>private
赋值兼容规则
前提:必须是public的继承方式
1.可以将子类对象直接赋值给基类对象,反之不可以
2.可以使用基类的指针(引用)指向一个基类的对象,反之不可以
同名隐藏
1.如果子类和基类中具有相同名称的成员变量,不管成员变量的类型是否相同,都优先访问子类的同名成员变量
如果需要通过子类对象访问基类中同名成员变量,则:
d.Base::_c='B';
2.成员方法和成员变量相同,相当于基类的成员方法/变量被隐藏了
不同继承方式&其对应的对象模型
1.单继承:子类只有一个基类
2.多继承:子类有多个基类,至少两个基类
子类对象中基类部分成员布局方式与继承列表中基类出现的先后次序一致
3.菱形继承:单继承和多继承的复合
二义性问题/数据冗余:通过派生类对象访问最顶层基类中成员或方法时存在二义性问题
解决方法:
1.访问明确化
d.C1::_b=1;
d.C2::_b=3;
2.从本质上解决——>让最顶层基类中的成员只有一份(虚拟继承)
4.虚拟继承
在继承列表中,基类继承权限前加上virtual关键字
虚拟继承对象大小比单继承对象大小多4个字节,因为多存储一个虚基表地址
虚拟继承的对象模型是倒立的,最前面是虚基表地址,再是子类新增,再是基类
最前面的地址指向虚基表(虚基表中存储偏移量表格),虚基表中存储基类部分成员起始位置相当于子类对象起始位置的偏移量
- 虚拟继承只在菱形虚拟继承中使用
最底层对象模型
C1 |
---|
C2 |
D类新增 |
B |