继承权限&访问限定符
基类private成员在派生类中是不能被访问的,如果基类成员不想在类外直接别访问,但需要在派生类中能访问,就定义为protect,保护成员限定符是因继承才出现的
public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象
protected/private继承是一个实现继承,基类的部分成员并非完全成为子类接口的一部分,是has-a的关系,所以非特殊情况下不会使用,大多数情况是用public。私有继承意味着is-implemented-in-terms-of(是根据...实现的)。通常比组合低级,但是当一个派生类需要访问基类保护成员或需要重定义基类的虚函数时就是合理的
不管哪种继承方式,在派生类内部都可以访问基类的公有成员和保护成员,基类的私有成员存在但是在子类中不可见
使用class关键字时,默认继承方式是private,使用struct默认继承方式是public
在实际运用中一般使用public继承,极少使用private/protected继承
赋值兼容规则--public继承:
子类对象可以赋值给父类对象
父类对象不能赋值给子类对象
父类的指针/引用可以指向子类对象
子类的指针/引用不能指向父类对象,可以通过强制类型转换,但不能调用成员函数,会崩溃
继承中的作用域:
在继承体系中基类和派生类都有独立的作用域
子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问。在子类成员函数中,可以使用 基类::基类成员 访问,
派生类默认成员函数
基类没有缺省构造函数,派生类必须要在初始化列表中显式给出基类名和参数列表
基类没有定义构造函数,则派生类也可以不用定义,全部使用缺省构造函数
基类定义了带有形参表构造函数,派生类就一定定义构造函数
继承与友元
友元关系不能继承,基类友元不能访问子类私有和保护成员
继承与static静态成员:
基类定义了static静态成员,则整个继承体系里面只有一个这样的成员,无论派生出多少个子类,都只有一个static成员实例
继承体系下派生类的对象模型
对象模型为对象中非静态成员变量在内存中的布局形式,与成员函数无关
单继承:一个子类只有一个直接父类称为单继承
多继承:一个子类有两个或以上直接父类称为多继承
菱形继承
菱形虚拟继承
访问继承于基类的成员变量时,会存在数据冗余和二义性的问题
虚拟继承--解决菱形继承的二义性和数据冗余的问题
在继承权限前加上virtual关键字即可构成虚拟继承
虚继承的特点--在任何派生类中的virtual基类总是用同一个(共享)对象表示
尽量不要设计菱形继承
虚继承和直接继承的区别:
时间:
在通过继承类对象访问虚基类对象中的成员(包括数据成员和函数成员)时,都必须通过某种间接引用来完成,这样会增加引用寻址时间(就和虚函数一样),其实就是调整this指针以指向虚基类对象,只不过这个调整是运行时间接完成的
空间:
由于共享所以不必要在对象内存中保存多份虚基类基类子类对象的拷贝,这样比多继承节省空间,虚拟继承与普通继承不同的是,虚拟继承可以防止出现菱形继承时,一个派生类中同时出现了两个基类的子对象。在虚拟继承情况下,基类子对象的布局是不同于普通继承的。因此,它需要多出一个指向基类子对象的指针