继承:
把公共特性抽象出来,放在父类(基类)中,可在原有基础上根据实际应用进行扩展,增加数据和功能,产生新的子类(派生类),实现代码的复用
继承方式与访问限定符
public, protected, private
- class 默认是private 私有继承(一般主动显示为public),struct 默认是 pubilc 公有继承
基类和派生类间的赋值兼容转换
Student s;
Person p = s
//天然支持。不存在类型转换也不产生临时变量,发生的是部分切片拷贝赋值
Person& rp = s;
// rp 指代子类中的父类部分
Person* ptrp = &s;
// 指针 ptrp 指向子类中的父类部分
- 认为父类不能向子类赋值
继承中的作用域
- 基类与派生类的作用域各自独立
- 基类派生类中的同名成员构成隐藏或重定义,需通过访问限定符指定访问
- 继承中的隐藏只需要函数名相同即可构成隐藏 (区分与函数重载)
- 构成隐藏的两个函数在不同的类域中,即不同作用域,而函数重载必须在同一作用域
- 尽量不定义重名成员
派生类中的默认成员函数
- 构造:子类部分子类处理,父类部分父类处理,先父后子
尽量显示拷贝构造和复制重载 - 析构:父类析构不用显示,在子类析构完后会自动调用父类析构,以保证先子后父的析构顺序(符合栈帧规则)
继承与友元
- 基类的友元关系不会被派生类继
- 派生类中可通过主动声明友元关系
- 静态成员是所有派生类共享的,基类和派生类中的静态成员是同一个
- 父类的构造或析构私有化,可实现一个不能被继承的类
菱形继承
菱形继承会导致数据冗余和二义性,通过在腰部设置虚继承解决问题
- 虚继承:
c++3.0引入虚继承,通过内存窗口观察虚继承
- 数据冗余部分存储了偏移量的地址
- 同类对象的编译表是同一块,指向的偏移量是同一块
继承与组合
- 继承(公有继承):is-a 关系,耦合度高,子类可以访问基类的公有、保护成员
- 组合:has-a 关系,耦合度低,子类可以访问基类公有成员,保护成员只能间接访问
- 若同时满足两种关系,建议使用has-a