继承的概念
继承机制是面向对象程序设计使代码复用的重要手段,它允许保持在原有类特性的基础上进行扩展增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构。
1.基类的private成员在派生类中无论以何种方式继承都是不可见的。这里的不可见指的是语法上限制派生类对象不管是在类里面还是类外都无法访问它。
2.基类的private成员在派生类中是无法被访问的,如果基类成员都不想在类外被访问,但需要在派生类中被访问,那么可以定义为protected。
3.使用关键字class是默认的继承方式是private,使用struct默认的继承方式是public。一般使用都是public,扩展维护性强。
基类和派生类对象赋值转换
1.派生类可以赋值给基类的对象/基类的指针/基类的引用。
2.基类对象不能给派生类赋值。
3.基类的指针可以通过类型强制转换赋值给派生类的指针,但是必须基类的指针是指向派生类对象时才是安全的。
继承中的作用域
在继承体系中,基类和派生类都有独立的作用域
子类和父类有同名成员,子类成员将屏蔽父类对同名函数的直接访问,这种情况叫隐藏也叫重定义。但是可以通过基类::基类成员访问。
如果成员函数隐藏,只需要函数名相同就能构成隐藏,但是在继承体系最好不要定义同名的成员。
派生类的默认成员函数
1.派生类的构造函数必须调用基类的构造函数初始化基类的的那一部分成员。如果没有默认的构造函数,则必须在派生类的构造函数初始化列表显示调用。
2.派生类的拷贝构造必须调用基类拷贝构造完成基类的拷贝初始化
3.派生类的operator=必须调用基类的operator=完成基类的赋值
4.派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。这样能保证派生类对象先清理派生类成员再清理基类成员的顺序
5.派生类对象初始化先调用基类构造再调用派生类构造
6.派生类对象析构清理先调用派生类再调用基类析构
继承与友元
友元不能被继承,也就是说基类友元不能访问子类私有和保护成员
继承与静态成员
基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一
个static成员实例。
菱形继承及菱形虚拟继承
菱形继承有数据冗余和二义性的问题,虚拟继承可以解决菱形继承的二义性和数据冗余的问题
虚拟继承解决数据冗余和二义性的原理
虚表指针和虚表,虚表中的偏移量,通过偏移量找到
继承和组合
1.public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。
2.组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。
3.在继承方式中,基类的内部细节对子类可见 。继承一定程度破坏了基类的封装,基类的改变,对派生类有很大的影响。派生和基类间的依赖关系很强,耦合度高
4.组合这种复用风格被称为黑箱复用,因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。 组合类之间没有很强的依赖关系,耦合度低。优先使用对象组合有助于你保持每个类被封装。