继承

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

 

class Base//基类
{
public:
Base()
{
     }
~Base()
{
     }
private:
int_pri;
protected:
int_pro;
public:
int_pub;
};
class Derive:public Base//派生类,除了构造函数和析构函数没被继承,其他都继承了
{
public:
Derive()
{
}
~Derive()
{
}
private:
int_dpri;
protected:
int_dpro;
public:
int_dpub;
};

注意;BaseDerive不属于同一作用域

若派生类继承基类的方式没有写,则默认继承方式为私有

友元函数不能被继承,除非在派生类中声明

 继承方式

基类的public成员基类的Protected成员基类的Private成员继承引起的访问控制关系变化概括


Public继承


仍为public成员


仍为Protected成员


不可见

基类的非私有成员在子类的访问属性都不变


Protected继承


变成Protected成员


仍为Protected成员


不可见

基类的非私有成员都成为子类的保护成员


Private继承


变成Private成员

变成Private成员


不可见

基类的非私有成员都成为子类的私有成员

继承关系中构造函数调用过程


wKioL1cV__3AS0-PAAANwiBWCoM562.png

继承关系中析构函数调用过程

wKioL1cWAE_Sxyj5AAAQHoSasxU459.png

说明

1.基类没有缺省构造函数,派生类必须要在初始化列表中显示给出基类名和参数列表。

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

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

 

四种编译器会自动合成缺省的构造函数的情况

1.类中包含的其他有默认构造函数的类的对象

2.基类有默认构造函数

3.带有虚函数的类

4.虚拟继承的类

 

 

 

【继承与转换】

1、子类对象可以赋值给父类对象,父类对象不能赋值给子类对象

2、父类的指针/引用可以指向子类对象,子类的指针/引用不能指向父类对象

 

总结

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

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

3protected/private继承是一个实现继承,基类的部分成员并非完全成为子类接口的一部分,是has-a的关系原则,所以非特殊情况下不会使用这两种继承关系,在绝大多数的场景下使用的都是公有继承。

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

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

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

 

【派生类的默认成员函数】

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

 

wKioL1cWATyjyETsAAAid-Thwlo807.png

【继承体系中的作用域】

1、在继承体系中基类和派生类是两个不同的作用域

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

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