C++特性继承

来源:互联网 发布:网络奖状称号大全 编辑:程序博客网 时间:2024/06/06 04:14

C++特性继承

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。这样产生新的类,称派生类。
继承关系如图所示,Class后面紧跟着的为派生类(亦称子类),是类的继承者,冒号后为继承关系,有公有(public)继承,保护(protected)继承,私有(private)继承三种继承关系,最后的为基类(亦称父类),是类的被继承者。
这里写图片描述
三种继承关系中基类的public成员可直接在类外访问,protected成员不可在类外被访问,但可在派生类中被访问,private成员在类外和派生类中均不可被访问。
派生类会从基类中继承其成员,也可拥有自己的public成员,protected成员,private成员,其大小等于基类中成员大小加上自己的成员大小。

#include<iostream>  using namespace std;class B{public:int a = 1;protected:int b = 2;private:int c = 3;};class D :public B{public:int d = 4;};int main(){    cout << sizeof(D) << endl;    return 0;}

派生类大小为基类中3个int型大小(12)加上它自己的1个int(4)型大小。
这里写图片描述
经过继承后,派生类中从基类继承的成员可能会发生访问权限改变。如继承类型为public继承,派生类从基类中继承的成员访问权限不变,如继承类型为protected继承,派生类从基类中继承的public成员访问权限降为protected,如继承类型为private继承,派生类从基类中继承的public成员,protected成员访问权限降为private。即继承类型权限为最高权限。
这里写图片描述
在派生类中访问从基类中继承的成员权限如下,即基类中public成员和protected成员在三种继承方式下均可在派生类中被访问,而private成员均不可在派生类中被访问。
这里写图片描述
public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。
protected/private继承是一个实现继承,基类的部分成员并非完全成为子类接口的一部分,是 has-a 的关系原则。
使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public。

如果在基类和派生类中有同名成员时访问哪一个类中成员呢?

#include<iostream>  using namespace std;class B{public:int a=1;protected:int b=2;private:int c=3;};class D :public B{public:int a=4;};int main(){    D d;    cout << d.a << endl;    return 0;}

这里写图片描述
继承体系中的作用域:
1. 在继承体系中基类和派生类是两个不同作用域。
2. 子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问。(在子类成员函数中,可以使用 基类::基类成员 访问)–隐藏 –重定义。
3. 注意在实际中在继承体系里面最好不要定义同名的成员。

继承与转换–赋值兼容规则–public继承:
1. 子类对象可以赋值给父类对象(切割/切片)
2. 父类对象不能赋值给子类对象
3. 父类的指针/引用可以指向子类对象
4. 子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)
这里写图片描述
这里写图片描述
友元与继承:
友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员。
继承与静态成员:
基类定义了static成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例。

单继承&多继承&菱形继承:
【单继承】
一个子类只有一个直接父类时称这个继承关系为单继承。
这里写图片描述
这里写图片描述
【多继承】
一个子类有两个或以上直接父类时称这个继承关系为多继承。继承先后顺序决定了空间中存储位置的先后顺序,先继承的在前。
这里写图片描述
这里写图片描述
【菱形继承】
两个子类有共同的父类,又同时被一个子类继承时称这个继承关系为菱形继承,也叫钻石继承。
这里写图片描述
但菱形继承会造成二义性问题,如在派生类assistant类中调用person类中继承成员时有2个调用可能。
这里写图片描述
二义性可通过虚拟继承的方法解决,方法为student类和teacher类继承person类时在冒号后加virtual,派生类大小会多4个字节。person类中继承成员会转移到assistant类空间末尾,student类和teacher类中会保存指向person类继承成员的偏移量表格指针及其自身类的继承成员,如图所示。
这里写图片描述
虚继承–解决菱形继承的二义性和数据冗余的问题:
1. 虚继承解决了在菱形继承体系里面子类对象包含多份父类对象的数据冗余&浪费空间的问题。
2. 虚继承体系看起来很复杂,在实际应用我们通常不会定义如此复杂的继承体系。一般不到万不得已都不要定义菱形结构的虚继承体系结构,因为使用虚继承解决数据冗余问题也带来了性能上的损耗。

0 0