protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。

一、继承的定义格式

lass DeriveClassName : acess-lable BaseClassName

  1. 派生类类名 继承权限 基类(父类)名

继承权限:指三种继承关系,public(公有继承)、protected(保护继承)、 private(私有继承)。

二、继承关系

在继承中,根据继承权限的不同,基类成员的访问权限会在派生类中发生适当的改变,下面我们对三种不同访问权限对基类成员在派生类中的访问权限的影响。

①继承权限为public时:

这个函数是上面派生类中的一个测试函数,我们可以看到,在派生类中,基类的公有成员和保护成员可以访问,但私有成员是不能被访问的

FunTest2函数是类外的一个测试函数,可以看到,在类外通过创建的派生类对象可以对基类中的公有成员进行访问,但保护成员和私有成员都不能被访问

②继承权限为protected时:

从截图中我们可以看见,派生类中的FunTest1函数中创建的对象可以对基类中的公有和保护成员变量进行访问,但不能对私有成员变量进行访问

FunTest3是派生类D中的一个函数,D是Deriver的一个派生类,可以看出,在D中,对象对基类Base中的公有、保护类型成员可以访问,而私有成员不能访问。

类外的测试函数FunTest2中,Base基类中的所有成员都不能被D类的对象进行访问
由此可以看出,Base基类中的成员变量在Derive继承下来后都把公有访问权限改成保护类型。

③继承权限为private时:

FunTest3是派生类D中的一个函数,D是Deriver的一个派生类,可以看出,在D中,对象对基类Base中的公有、保护和私有类型也都不可以访问。

由此可以看出,Base基类中的成员变量在Derive继承下来后都把访问权限改成了私有类型

总结

继承关系 - 图1
1. 基类的 private成员在派生类中是不能被访问的,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。

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

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

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

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

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

    三、构造函数

    从运行结果看,是先调用基类的构造函数,然后调用派生类的构造函数,再调用派生类的析构函数,最后调用基类的析构函数

编译角度看
所以说编译器实际上是先调用派生类的构造函数的,但编译器是在什么时候调用的呢?其实编译器是先进入派生类的构造函,然后在初始化列表处调用了基类的构造函数,然后再回来执行自己的函数体。构造函数说清楚了,析构函数的调用顺序似乎还是很模糊,编译器为什么会先调用派生类的析构函数呢?这个编译器是根据生命周期的长短来调用的,派生类中构造函数生命周期比基类的生命周期短,所以就先调用派生类的析构函数。

【说明】

1、基类没有缺省构造函数,派生类必须要在初始化列表中显式给出基类名和参数列表。
2、基类没有定义构造函数,则派生类也可以不用定义,全部使用缺省构造函数。
3、基类定义了带有形参表构造函数,派生类就一定定义构造函数。

四、继承体系中的作用域

  1. 在继承体系中基类和派生类是两个不同作用域。
    2. 子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问。(在子类成员函数中,可以使用 基类::基类成员 访问)—隐藏—重定义
    从截图中看出,只改变了派生类中成员的值,这就是由于基类和派生类中使用了同名的成员变量,而派生类中的成员变量对基类中的同名成员变量形成了覆盖/重定义。
    3. 注意在实际中在继承体系里面最好不要定义同名的成员。

什么是多重继承二义性?

A.派生类的多个基类中存在同名成员时,派生类对这个成员访问可能出现二义性
B.一个派生类是从具有共同的间接基类的两个直接基类派生来的,派生类对该公共基类的访问可能出现二义性
C.解决二义性最常用的方法是作用域运算符对成员进行限定

五、继承与转换—赋值兼容规则—public继承

public继承是保持is-a的原则,每个子类对象也是一个父类对象,但由于子类对象添加了新的功能,所以,一个父类对象并不是一个子类对象,所以父类对象不能给子类对象赋值。

  1. 子类对象可以赋值给父类对象(切割/切片)。
    2. 父类对象不能赋值给子类对象。
    3. 父类的指针/引用可以指向子类对象
    4. 子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)

    六、友元关系不继承

    [

](https://blog.csdn.net/eagle_1036077338/article/details/53081075)
[

](https://blog.csdn.net/eagle_1036077338/article/details/53081075)
[

](https://blog.csdn.net/eagle_1036077338/article/details/53081075)