c++ 继承

来源:互联网 发布:java枚举类型有什么用 编辑:程序博客网 时间:2024/06/07 10:14

1.继承概念

继承概念

继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。

继承格式

class DerivedClassName:public BaseClassName

class DerivedClassName:protected BaseClassName

class DerivedClassName:private BaseClassName

2.继承关系&访问访问符

public 继承 :      public protected private(不可见)

protected 继承: public protected private(不可见)

private继承:       public protected private(不可见)

总结:

1).基类的private成员在派生类中不可访问,而protected在类外不可访问,派生类中能访问。

2).public继承是一种接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。

3).protected/private继承是一个实现继承,基类的部分成员并非完全成为子类接口的一部分,是has-a的关系原则,所以非特殊情况下不会使用这两种继承关系,在绝大多数的场景下使用的都是公有继承。私有继承以为这is-implemented-in-terms-of(是根据......实现的)。通常比组合(composition)更低级,但当一个派生类需要访问基类保护成员或需要重定义基类的虚函数是它就是合理的。

4).不管是哪种继承方式,在派生类内部都可以访问基类的公有成和保护成员,基类的私有成员存在但是在子类中不可见(不能访问)。

5).使用关键字class是默认的继承方式private,使用struct是默认的继承方式是public,不过最好显式地写出继承方式。

6).在实际运用中一般使用都是public继承,极少场景下才会使用protected/private继承。

3.派生类的默认成员函数

在继承关系里面,在派生类中如果没有显式定义这六个成员函数,编译系统则会默认合成这六个默认成员函数。


继承关系中构造函数调用顺序


若基类中的构造函数有参数,且不为缺省,则需在派生类的构造函数在初始化列表中显式调用基类构造函数。

函数体调用顺序是

base->Derived

【说明】

1).基类没有缺省构造函数,派生类必须 要在初始化列表中显式给出积累名称的参数列表。

2).基类没有定义构造函数,则派生类也可以不用定义,全部用缺省构造函数。

3).基类定义了带有形参构造函数,派生类就一定定义构造函数。

【析构顺序】

Derived->base

4. 继承体系中的作用域


1).在继承体系基类和派生类是;两个不同作用域。

2).子类的父类中有同名成员,子类成员将屏蔽父类对成员的直接访问。(在子类成员函数中,可以使用 基类::基类成员 访问)--隐藏 --重定义

3).注意在实际中继承体系里面最好不要定义同名的成员。

5.继承与 转换--赋值兼容规则--public继承


1).子类对象可以赋值给父类对象。

2).父类对象不能赋值给子类对象。

3).父类的指针/引用可以指向子类对象。

4).子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)。

友元与继承

友元关系不能继承,也就是说基类友元不能访问子类私和保护成员。

继承与静态成员

基类定义了static成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子类,都只有一个static成员实例。

6.单继承&多继承&菱形继承

单继承


一个子类只有一个直接父类是称这个继承关系为单继承。

多继承


一个子类有两个或以上直接父类是称这个继承关系为多继承

菱形继承


Assistant的对象中有两份Perso成员菱形继承存在二义性的数据冗余的问题

虚继承--解决菱形继承的二义性和冗余的问题


1).虚继承解决了在菱形继承体系里面子类对象包含多份父类对象的数据冗余&;浪费空间的问题。


2).虚继承体系看起来好复杂,在实际应用我们通常不会定义如此复杂的继承体系。一般不到万不得已都不要定义菱形结构的虚继承体系结构,因为使用虚继承解决数据冗余问题也带来了性能上的损耗。

图中解决二义性时在VS下使用的是偏移量,而不是图中直接的指针指向,这里只为了更直观的展示。

0 0
原创粉丝点击